-- SPDX-License-Identifier: GPL-3.0-or-later

local extension = Package:new("old2")
-- extension.extensionName = "vupslash"
extension.extensionName = "VslTest"
-- extension.game_modes_whitelist = { 'nos_heg_mode', 'new_heg_mode' }
-- dofile "packages/vupslash/game_rule.lua"

-- local VslUtil = require "packages/vupslash/util"
local VslUtil = require "packages/VslTest/util"

local U = require "packages/utility/utility"

--------------------------------------------------
--测试技能：超级英姿
--------------------------------------------------

local super_yingzi = fk.CreateTriggerSkill{
	name = "superyingzi",
	anim_type = "drawcard",
	events = {fk.DrawNCards},
	on_use = function(self, event, target, player, data)
		data.n = data.n + 20
	end,
}

--------------------------------------------------
--测试技能：摸指定牌
--------------------------------------------------

local v_cheat = fk.CreateActiveSkill{
	name = "v_cheat",
	anim_type = "drawcard",
	can_use = function(self, player)
		return true
	end,
	on_use = function(self, room, effect)
		local from = room:getPlayerById(effect.from)
		local cardTypeName = room:askForChoice(from, { 'basic', 'trick', 'equip' }, "cheat")
		local cardType = Card.TypeBasic
		if cardTypeName == 'trick' then
			cardType = Card.TypeTrick
		elseif cardTypeName == 'equip' then
			cardType = Card.TypeEquip
		end

		local allCardIds = Fk:getAllCardIds()
		local allCardMapper = {}
		local allCardNames = {}
		for _, id in ipairs(allCardIds) do
			local card = Fk:getCardById(id)
			if card.type == cardType then
				if allCardMapper[card.name] == nil then
					table.insert(allCardNames, card.name)
				end

				allCardMapper[card.name] = allCardMapper[card.name] or {}
				table.insert(allCardMapper[card.name], id)
			end
		end

		if #allCardNames == 0 then
			return
		end

		local cardName = room:askForChoice(from, allCardNames, "cheat")
		local toGain = nil
		if #allCardMapper[cardName] > 0 then
			toGain = allCardMapper[cardName][math.random(1, #allCardMapper[cardName])]
		end

		from:addToPile(self.name, toGain, true, self.name)
		room:obtainCard(effect.from, toGain, true, fk.ReasonPrey)
	end
}
  
--------------------------------------------------
--测试技能：流失体力
--------------------------------------------------

local v_lose = fk.CreateActiveSkill{
	name = "v_lose",
	anim_type = "offensive",
	can_use = function(self, player)
		return true
	end,
	target_num = 1,
	-- card_num = 1,
	card_filter = function(self, to_select, selected, selected_targets)
		return false
		-- if #selected == 1 then return false end
		-- return Fk:currentRoom():getCardArea(to_select) ~= Player.Equip
	end,
	target_filter = function(self, to_select, selected)
		-- local target = Fk:currentRoom():getPlayerById(to_select)
		return #selected == 0
	end,
	on_use = function(self, room, effect)
		local player = room:getPlayerById(effect.from)
		local target = room:getPlayerById(effect.tos[1])
		room:loseHp(target, 1, self.name)
	end,
}

--------------------------------------------------
--扬音
--------------------------------------------------

Fk:addPoxiMethod{
  name = "v_yangyin_choose",
  card_filter = function(to_select, selected)
    local choose = true
    local type = Fk:getCardById(to_select).type
    for _, id in ipairs(selected) do
      if type == Fk:getCardById(id).type then
        choose = false
        break
      end
    end
    return choose
  end,
  feasible = function(selected)
    return #selected >= 0 or #selected <= 3
  end,
  prompt = function ()
    return Fk:translate("#v_yangyin_detail")
  end
}

local v_yangyin = fk.CreateTriggerSkill{
  name = "v_yangyin",
  anim_type = "drawcard",
  events = {fk.DrawNCards},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.DrawNCards then
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.DrawNCards then
      local cids = room:getNCards(4)
      -- room:moveCards({
      --   ids = cids,
      --   toArea = Card.Processing,
      --   moveReason = fk.ReasonPut,
      -- })
      local get = room:askForPoxi(player, "v_yangyin_choose", {
        { self.name, cids },
      }, nil, false)
      if #get > 0 then
        local dummy = Fk:cloneCard("dilu")
        dummy:addSubcards(get)
        room:obtainCard(player.id, dummy, true, fk.ReasonPrey)
      end
      cids = table.filter(cids, function(id) return not table.contains(get, id) end)
      if #cids > 0 then
        room:askForGuanxing(player, cids)
      end
      data.n = 0
    end
  end,
}

--------------------------------------------------
--惊弦
--据说原版借刀杀人+闪触发两次技能且会排除掉被要求使用杀的倒霉蛋
--我们这只会触发借刀杀人这次，屏蔽那个倒霉蛋。
--------------------------------------------------

local v_jingxian = fk.CreateTriggerSkill{
  name = "v_jingxian",
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return
      target == player and
      player:hasSkill(self) and
      player.phase ~= Player.NotActive and
      (data.card and 
        (data.card.type == Card.TypeBasic 
        or (data.card.type == Card.TypeTrick and data.card.subtype ~= Card.SubtypeDelayedTrick))
      )
      and data.tos and #TargetGroup:getRealTargets(data.tos) > 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = {}
    for _,p in ipairs(room:getAlivePlayers()) do
      if (not table.contains(TargetGroup:getRealTargets(data.tos), p.id)) and VslUtil.SkillCanTarget(p, player, self.name) then
        table.insert(targets, p.id)
      end
    end
    if #targets > 0 then
      local tar = room:askForChoosePlayers(player, targets, 1, 1, "#v_jingxian_choice:::"..data.card.name, self.name, true)[1]
      if tar then
        self.cost_data = tar
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tar = room:getPlayerById(self.cost_data)
    tar:drawCards(1, self.name)
    --这里后续可以补candiscard
    if not tar:isNude() then
      local prompt = "#v_jingxian_throw::"..tar.id
      -- local buddy = false
      -- if table.contains(player.buddy_list, tar.id) then
      --   player:removeBuddy(tar)
      --   buddy = true
      -- end
      local cid = room:askForCardChosen(player, tar, "he", self.name, prompt)
      -- if buddy then
      --   player:addBuddy(tar)
      -- end

      room:throwCard({cid}, self.name, tar, player)
    end  
  end,
}

--------------------------------------------------
--山椒阿露波
--------------------------------------------------

local shanjiaoalubo_liuciyuanouxiang = General(extension,"shanjiaoalubo_liuciyuanouxiang", "xuyanshe", 3, 3, General.Female)
shanjiaoalubo_liuciyuanouxiang:addSkill(v_yangyin)
shanjiaoalubo_liuciyuanouxiang:addSkill(v_jingxian)

--------------------------------------------------
--离鸢
--减距离不行，加距离可以（？）
--------------------------------------------------

local v_liyuan_buff = fk.CreateDistanceSkill{
  name = "#v_liyuan_buff",
  correct_func = function(self, from, to)
    local X = 0
    if from.id ~= to.id 
      -- and (from:hasSkill(self) or to:hasSkill(self)) 
    then
      if from:hasSkill(self) then
        X = X + from:getMark("@v_liyuan")
      end
      if to:hasSkill(self) then
        X = X + to:getMark("@v_liyuan")
      end
      return X
    end
  end,
}

local v_liyuan = fk.CreateTriggerSkill{
  --（刚需）技能认证名
  name = "v_liyuan",
  --(非必要）赋予进攻型技能定义
  anim_type = "offensive",
  --技能为锁定技，满足条件后强制发动
  -- frequency = Skill.Compulsory,
  --时机：受到伤害后，造成伤害后
  events = {fk.Damage,fk.Damaged},
  --触发条件：
  --（受到伤害时）触发时机的角色为遍历到的角色、遍历到的角色具有本技能、牌为实体牌、牌的种类为锦囊牌、造成的伤害大于0。
  --（造成伤害时）造成伤害的来源为遍历到的角色、遍历到的角色具有本技能、牌为实体牌、牌的种类为锦囊牌、造成的伤害大于0。
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      data.damage > 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt
    local skill_use
    if event == fk.Damage then
      prompt = "#v_liyuan_dec_choice"
      skill_use = room:askForSkillInvoke(player, self.name, data, prompt)
      self.cost_data = "v_liyuan_dec"
    elseif event == fk.Damaged then
      prompt = "#v_liyuan_inc_choice"
      skill_use = room:askForSkillInvoke(player, self.name, data, prompt)
      self.cost_data = "v_liyuan_inc"
    end
    if skill_use then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.Damage and self.cost_data == "v_liyuan_dec" then
      -- room:addPlayerMark(player, "@v_liyuan", -1)
      local num = player:getMark("@v_liyuan")
      room:setPlayerMark(player, "@v_liyuan", num - 1)
    elseif event == fk.Damaged and self.cost_data == "v_liyuan_inc" then
      room:addPlayerMark(player, "@v_liyuan", 1)
    end
  end,
}

v_liyuan:addRelatedSkill(v_liyuan_buff)

--------------------------------------------------
--不倦
--可以考虑为了这个技能做一个在特定时机可以更新的标记用来记录和不同角色的距离
--------------------------------------------------

local v_bujuan = fk.CreateActiveSkill{
  name = "v_bujuan",
  anim_type = "offensive",
  prompt = "#v_bujuan_act",
  min_card_num = 1,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 1
  end,
  card_filter = function(self, to_select, selected)
    return Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand
  end,
  target_filter = function(self, to_select, selected, cards)
    local room = Fk:currentRoom()
    local tar = room:getPlayerById(to_select)
    local x = Self:distanceTo(tar)
    return #cards == x and #selected == 0 and to_select ~= Self.id 
      and VslUtil.SkillCanTarget(tar, Self, self.name)
  end,
  on_use = function(self, room, effect)
    local cards = effect.cards
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    if #cards > 0 then
      room:throwCard(cards, self.name, player, player)
    end
    if target and target:isAlive() then
      room:damage{
        from = player,
        to = target,
        damage = 1,
        skillName = self.name,
      }
    end
  end,
}

--------------------------------------------------
--新黎歌
--角色马克：
--------------------------------------------------

local lige_jiuyixinsheng = General(extension, "lige_jiuyixinsheng", "xuyanshe", 3, 3, General.Female)
lige_jiuyixinsheng:addSkill(v_liyuan)
lige_jiuyixinsheng:addSkill(v_bujuan)

--------------------------------------------------
--浅唱
--------------------------------------------------

local v_qianchang = fk.CreateViewAsSkill{
  name = "v_qianchang",
  interaction = UI.ComboBox {choices = VslUtil.not_damage_tricks},
  enabled_at_play = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and not player:isKongcheng()
  end,
  card_filter = function()
    return false
  end,
  view_as = function(self, cards)
    local card = Fk:cloneCard(self.interaction.data)
    card:addSubcards(Self:getCardIds(Player.Hand))
    card.skillName = self.name
    return card
  end,
}

--------------------------------------------------
--明贤
--TODO: 
--------------------------------------------------

local v_mingxian = fk.CreateTriggerSkill{
  name = "v_mingxian",
  --赋予防御型技能定义,
  anim_type = "defensive",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  --时机：目标确定后
  events = {fk.TargetSpecified},
  --触发条件：
  --         遍历到的角色具有本技能
  --         存在卡，且卡的真名为“杀”
  --         卡的颜色为红色/卡的名字为“雷杀”
  --         使用牌的角色存在、使用牌的角色存活、使用牌的角色不为遍历到的角色
  --         牌的目标存在，牌的目标中存在遍历到的角色
  --         本次流程中第一次触发这个时机
  can_trigger = function(self, event, target, player, data)
    local room = player.room
    local pla = room:getPlayerById(data.from)
    local target_contain_player = false
    for _, p in ipairs(AimGroup:getAllTargets(data.tos)) do
      if p == player.id then
        target_contain_player = true
      end
    end
    return player:hasSkill(self) 
    and data.card and data.card.trueName == "slash" 
    and (data.card.color == Card.Red or data.card.name == "thunder__slash")
    and pla and pla:isAlive() and pla ~= player
    and #AimGroup:getAllTargets(data.tos) > 0 and target_contain_player
    and data.firstTarget
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local pla = room:getPlayerById(data.from)
    --if data.from ~= player then
    --doindicate的两个参数均为integer类型，一般为角色id
    room:doIndicate( pla.id, {player.id} )
    --end
    --询问是否交对应的牌，如存在，继续，否则失效。
    local prompt = "#v_mingxian_give:"..player.id
    local slash_or_not = room:askForCard(pla, 1, 1, false, self.name, true,"slash|.|.|hand" ,prompt)[1]
    if slash_or_not then
      room:obtainCard(player, slash_or_not, true, fk.ReasonGive)
    else
      local address = "./packages/"..VslUtil.extensionName.."/image/anim/skill_nullify"
      room:setEmotion(player, address)
      table.insert(data.nullifiedTargets, player.id)
    end
  end,
}

--------------------------------------------------
--诗小雅
--角色马克：
--------------------------------------------------

local shixiaoya_xianyadan = General(extension,"shixiaoya_xianyadan", "chaociyuan", 3, 3, General.Female)
shixiaoya_xianyadan:addSkill(v_qianchang)
shixiaoya_xianyadan:addSkill(v_mingxian)

--------------------------------------------------
--抹挑
--技能马克：
-- “本回合至多造成一次伤害”后续可以补动画。
--注释：本技能将导致造成一次伤害后，伤害传导也无效。
--------------------------------------------------

local v_motiao_invalidity = fk.CreateInvaliditySkill {
  name = "#v_motiao_invalidity",
  invalidity_func = function(self, from, skill)
    if from:getMark("@@v_motiao_invalidity-turn") > 0 then
      return skill:isEquipmentSkill()
    end
  end
}
local v_motiao = fk.CreateTriggerSkill{
  name = "v_motiao",
  --赋予摸牌型技能定义
  anim_type = "drawcard",
  --时机：阶段开始时，目标指定后
  events = {fk.EventPhaseStart, fk.TargetSpecified},
  --触发条件：
  --（阶段开始时）触发时机的角色为遍历到的角色；遍历到的角色具有本技能；
  --              被遍历到的角色处于回合开始阶段。
  --（目标指定时）触发时机的角色为遍历到的角色；遍历到的角色具有本技能；
  --             存在回合开始阶段时使用此技能的标签；
  --             被指定的角色中存在遍历到的角色。
  --             本次流程中第一次触发这个时机
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return target == player and player:hasSkill(self)
      and player.phase == Player.Start
    elseif event == fk.TargetSpecified then
      local room = player.room
      --遍历所有被指定到的角色，确认是否存在遍历到的角色
      local motiao_useornot = false
      local targets = data
      local motiao_tar = AimGroup:getAllTargets(targets.tos)
      for _, p in ipairs(motiao_tar) do
        local pls = room:getPlayerById(p)
        if pls == player then
          motiao_useornot = true
        end
      end
      return target == player and player:hasSkill(self)
      and player:getMark("v_motiao_using-turn") > 0
      and motiao_useornot
      and targets.firstTarget
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    --确认是否发动技能。
    if event == fk.EventPhaseStart then
      local prompt = "v_motiao_choice"
      if room:askForSkillInvoke(player, self.name, data, prompt) then
        return true
      end
    --满足技能发动要求后，锁定发动。
    elseif event == fk.TargetSpecified and player:getMark("v_motiao_using-turn") > 0 then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    --以on_cost中做出选择为代价，本回合内你只能造成1点伤害，你使用牌指定自己为目标之一后，摸一张牌。
    if event == fk.EventPhaseStart then
      room:setPlayerMark(player, "v_motiao_using-turn", 1)
      room:setPlayerMark(player, "@@v_motiao_using-turn", 1)
      room:setPlayerMark(player, "@@v_motiao_invalidity-turn", 1)
    --摸一张牌
    elseif event == fk.TargetSpecified then
      player:drawCards(1, self.name)
    end
  end,

  -- 伤害及抹挑装备失效在这里刷新。
  refresh_events = {fk.DamageCaused, fk.Damage},
  -- 刷新时机：
  --             触发时机的角色为遍历到的角色；遍历到的角色具有本技能；
  --             存在回合开始阶段时使用此技能的标签；
  --             造成的伤害大于0；
  --             非光属性伤害（暂未实装）。
  can_refresh = function(self, event, target, player, data)
    if not (target == player and player:hasSkill(self)) then
      return false
    end
    if event == fk.DamageCaused or event == fk.Damage then
      return player:getMark("v_motiao_using-turn") > 0
        and data.damage > 0
    -- elseif event == fk.EventPhaseChanging then
    --   return target == player and player:getMark("@@v_motiao_invalidity") > 0
    --   and data.from == Player.NotActive and data.to ~= Player.NotActive
    --   return player:getMark("v_motiao_using-turn") > 0
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.DamageCaused then
      if player:getMark("@@v_motiao_after-turn") > 0 then
        local address = "./packages/"..VslUtil.extensionName.."/image/anim/skill_nullify"
        room:setEmotion(data.to, address)
        room:sendLog{
          type = "#defense_damage",
          from = player.id,
          --log.to是数组
          to = {data.to.id},
          arg = self.name,
          arg2 = data.damage,
        }
        data.damage = 0
      end
    elseif event == fk.Damage then
      room:setPlayerMark(player, "@@v_motiao_using-turn", 0)
      room:setPlayerMark(player, "@@v_motiao_after-turn", 1)
    -- elseif event == fk.EventPhaseChanging then
    --   room:setPlayerMark(player, "@@v_motiao_invalidity", 0)
    end
  end
}
v_motiao:addRelatedSkill(v_motiao_invalidity)

--------------------------------------------------
--连奏
--技能马克：打出的牌可能会无法返回number；丈八在下版本前可能还是算点数的。
--------------------------------------------------

local v_lianzou = fk.CreateTriggerSkill{
  name = "v_lianzou",
  --赋予摸牌型技能定义
  anim_type = "drawcard",
  --时机：阶段结束时
  events = {fk.EventPhaseEnd},
  --触发条件：
  --（阶段结束时）触发时机的角色为遍历到的角色；遍历到的角色具有本技能；
  --              被遍历到的角色处于出牌阶段。
  --              被遍历到的角色本轮使用/打出牌的点数之和>=50（打出是否算入在内待定）
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
    and player.phase == Player.Play
    and player:getMark("@v_lianzou_count-turn") >= 50
  end,
  on_cost = function(self, event, target, player, data)
    --确认是否发动技能。
    local room = player.room
    if room:askForSkillInvoke(player,self.name,data) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    --判定直到点数大于等于50
    if event == fk.EventPhaseEnd then
      --这里可以后续放限定动画并给大概2500ms的延时+音效。
      local count = 0
      local dummy = Fk:cloneCard("slash")
      while count < 50 do
        local judge = {
          who = player,
          reason = self.name,
          pattern = ".|1~"..(50-count).."|.",
        }
        room:judge(judge)
        local result = judge.card
        count = count + result.number
        if count < 50 then
          dummy:addSubcard(result)
        end
      end
      room:obtainCard(player.id, dummy, true)
    end
  end,

  --刷新时机：手牌结算后，手牌打出结算后（本时机伴随希贝尔上线，与之同步因此删除）
  refresh_events = {fk.CardUseFinished},
  --刷新条件
  --（手牌结算后，手牌打出结算后（这个待定））
  --             触发时机的角色为遍历到的角色；遍历到的角色具有本技能；
  --              被遍历到的角色处于出牌阶段。
  can_refresh = function(self, event, target, player, data)
    -- if not (target == player and player:hasSkill(self)) then
    --   return false
    -- end
    return target == player and player:hasSkill(self)
    and player.phase == Player.Play
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    --在满足以下条件的前提下，将牌的点数加入某个mark里。
    -- 卡牌存在，为实体牌, 卡牌点数小于等于13大于0。
    local card = data
    if card.card and card.card.id > 0 and card.card.number <= 13 and card.card.number > 0 then
      room:addPlayerMark(player, "@v_lianzou_count-turn", card.card.number)
    end
  end
}

--------------------------------------------------
--弦羽
--角色马克：抹挑
--------------------------------------------------

local xianyu_xiangluancuxian = General(extension,"xianyu_xiangluancuxian", "chaociyuan", 3, 3, General.Female)
xianyu_xiangluancuxian:addSkill(v_motiao)
xianyu_xiangluancuxian:addSkill(v_lianzou)

--------------------------------------------------
--婉龙
--------------------------------------------------

local v_wanlong = fk.CreateTriggerSkill{
  name = "v_wanlong",
  anim_type = "drawcard",
  -- frequency = Skill.Compulsory,
  events = {fk.DrawNCards},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.DrawNCards
        and data.n > 0
        and player:getMark("@v_wanlong") < 8
      then
        return true
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local num = 8 - player:getMark("@v_wanlong")
    local prompt = "#v_wanlong_choice:::"..num
    if room:askForSkillInvoke(player, self.name, data, prompt) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.DrawNCards then
      data.n = data.n - 1
      --这里可以加技能失效，或者data.n在前面处理
      room:addPlayerMark(player, "@v_wanlong", 1)
      local X = 9 - player:getMark("@v_wanlong")
      local can_get_ids = {}
      for _, id in ipairs(room.draw_pile) do
        if Fk:getCardById(id).number == X then
          table.insertIfNeed(can_get_ids, id)
        end
      end
      if #can_get_ids > 0 then
        local to_return = table.random(can_get_ids, 1)
        local choice = "confirm"
        local get, top
        local result = room:askForCustomDialog(player, self.name,
        "packages/utility/qml/ChooseCardsAndChoiceBox.qml", {
          can_get_ids,
          {"confirm"},
          "#v_wanlong_get_choice",
          {},
          1,
          1,
        })
        if result ~= "" then
          local reply = json.decode(result)
          to_return = reply.cards
          choice = reply.choice
        end
        if to_return[1] and to_return[1] ~= -1 then
          local idcard = Fk:getCardById(to_return[1])
          room:obtainCard(player, idcard, true, fk.ReasonPrey)
          room:delay(500)
        end
      else
        room:sendLog{
          type = "#v_player_find_number_fail",
          arg = X,
        }
      end
    end
  end,
}

--------------------------------------------------
--月潮
--------------------------------------------------

local v_yuechao = fk.CreateTriggerSkill{
  name = "v_yuechao",
  anim_type = "control",
  events = {fk.Damaged, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if not (player:hasSkill(self)
      and player.phase == Player.NotActive
      and player:usedSkillTimes(self.name, Player.HistoryRound) < 1)
    then 
      return false
    end
    if event == fk.Damaged then
      return target == player
        and data.damage > 0
    elseif event == fk.AfterCardsMove then
      if not player:isKongcheng() then
        return
      end
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              return true
            end
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = {}
    local alives = room:getAlivePlayers()
    local prompt = "#v_yuechao_choice"
    for _,p in ipairs(alives) do
      local cids = p:getCardIds("ej")
      --后续可以在这里补充以下判定：
      -- caneffect，目标可以弃置遍历到的角色的牌(candiscard)。
      if #cids > 0 
        and VslUtil.SkillCanTarget(p, player, self.name) 
      then
        table.insert(targets, p.id)
      end
    end
    if #targets > 0 then
      local ret = room:askForChoosePlayers(player, targets, 1, 1, prompt, self.name, true)
      --确认是否发动技能。
      if #ret > 0 then
        --后续可以在这里补充以下判定：
        -- 遍历到的角色本技能未被元初之类的无效，目标可以弃置遍历到的角色的牌。
        self.cost_data = ret[1]
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tar = room:getPlayerById(self.cost_data)
    room:addPlayerMark(player, "@@v_yuechao_used-round", 1)
    local cid = room:askForCardChosen(player, tar, "ej", self.name)
    local card = Fk:getCardById(cid)
    room:obtainCard(player, card, true, fk.ReasonPrey)
    if VslUtil.canUseCard(room, player, card) 
      and table.contains(player:getCardIds(Player.Hand), cid)
    then
      VslUtil.askForUseRealCard(room, player, {cid}, ".", self.name, "#v_yuechao_use")
    end
  end,
}

--------------------------------------------------
--月兮
--------------------------------------------------

local yuexi_ruoyuelongnv = General(extension,"yuexi_ruoyuelongnv", "TheVirkyrie", 3, 3, General.Female)
yuexi_ruoyuelongnv:addSkill(v_wanlong)
yuexi_ruoyuelongnv:addSkill(v_yuechao)

--------------------------------------------------
--贵胄
--------------------------------------------------

local v_guizhou = fk.CreateTriggerSkill{
  name = "v_guizhou",
  anim_type = "defensive",
  events = {fk.TargetConfirming},
  can_trigger = function(self, event, target, player, data)
    --后续可以在这里增加伤害来源是否可以对目标使用杀的判定canuse，可以参考官方的utility改良一下；
    --避免如鬼勇之类的技能的问题。
    local ret = target == player and player:hasSkill(self) and
      (data.card.trueName == "slash" or data.card.name == "duel" )
    if ret then
      self.target_list = {}
      local room = player.room
      for _, p in ipairs(room:getOtherPlayers(player)) do
        if p.id ~= data.from and p:inMyAttackRange(player) then
          table.insert(self.target_list, p.id)
        end
      end
      return #self.target_list > 0
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "#v_guizhou_target:"..data.from.."::"..data.card.name
    local plist, cid = room:askForChooseCardAndPlayers(player, self.target_list, 1, 1, nil, prompt, self.name, true)
    if #plist > 0 then
      self.cost_data = {plist[1], cid}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = self.cost_data[1]
    room:doIndicate(player.id, { to })
    if not data.card:isVirtual() then
      room:sendLog{
        type = "#v_guizhou_log",
        from = data.from,
        to = { to },
        arg = self.name,
        card = { data.card.id },
      }
    elseif data.card:isVirtual() then
      room:sendLog{
        type = "#v_guizhou_virtual_log",
        from = data.from,
        to = { to },
        arg = self.name,
        arg2 = data.card:toLogString(),
      }
    end
    room:throwCard(self.cost_data[2], self.name, player, player)
    TargetGroup:removeTarget(data.targetGroup, player.id)
    TargetGroup:pushTargets(data.targetGroup, to)
  end,
}

--------------------------------------------------
--苦情
--技能马克：
--------------------------------------------------

local v_kuqing = fk.CreateTriggerSkill{
  name = "v_kuqing",
  --赋予控场型技能定义
  anim_type = "control",
  --时机：受到伤害后
  events = {fk.Damaged},
  --触发条件：
  -- 遍历到的角色具有本技能
  -- 伤害大于0，触发时机的角色处于遍历到的角色攻击范围内
  -- 触发时机的角色区域内有牌
  can_trigger = function(self, event, target, player, data)
    local damage = data
    return player:hasSkill(self) 
    and damage.damage > 0 and player:inMyAttackRange(target)
    and (not target:isNude())
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "#v_kuqing_use:"..target.id
    if (not player:isKongcheng()) then
      local ret = room:askForDiscard(player, 1, 1, false, self.name, true, ".", prompt)
      --需要的话在这里增加技能检测失效
      if #ret > 0 then
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    -- local buddy = false
    -- if table.contains(player.buddy_list, target.id) then
    --   player:removeBuddy(target)
    --   buddy = true
    -- end
    local card = room:askForCardChosen(player, target, "he", self.name)
    -- if buddy then
    --   player:addBuddy(target)
    -- end

    room:obtainCard(player.id, card, false)
  end,
}

--------------------------------------------------
--诺拉
--角色马克：
--------------------------------------------------

local nuola_canglangzhixin = General(extension,"nuola_canglangzhixin", "RainbowPro", 3, 3, General.Female)
nuola_canglangzhixin:addSkill(v_guizhou)
nuola_canglangzhixin:addSkill(v_kuqing)

--------------------------------------------------
--应激
--------------------------------------------------

local v_yingji_buff = fk.CreateTargetModSkill{
  name = "#v_yingji_buff",
  residue_func = function(self, player, skill, scope, card)
    if player:getMark("@@v_yingji-turn") > 0 then
      return 999
    end
  end,
  distance_limit_func =  function(self, player, skill, card)
    if player:getMark("@@v_yingji-turn") > 0 then
      return 999
    end
  end,
}
local v_yingji = fk.CreateTriggerSkill{
  name = "v_yingji",
  --赋予卖血型技能定义
  anim_type = "masochism",
  --时机：受到伤害后
  events = {fk.Damaged},
  --触发条件：触发时机的角色为遍历到的角色、遍历到的角色具有本技能，伤害大于0，存在伤害来源，伤害来源存活。
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) 
    and data.damage > 0 and data.from and data.from:isAlive()
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "v_yingji_choice:"..data.from.id
    if room:askForSkillInvoke(player, self.name, data, prompt) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    --执行判定，判定如为锦囊牌，则触发效果。
    local room = player.room
    if player.id ~= data.from.id then
      room:doIndicate( player.id, {data.from.id} )
    end
    --如果存在skillnullify和caneffect，可以考虑在这里放无效。
    data.from:turnOver()
    data.from:drawCards(1, self.name)
    room:setPlayerMark(data.from, "@@v_yingji-turn", 1)
  end,
}
v_yingji:addRelatedSkill(v_yingji_buff)

--------------------------------------------------
--附身
--1. 需要为extra_turn的tag处理做额外skill，以及技能发动判定也要注意
--2. 需要为技能开始和结束做两种判定逻辑···
--3. 安装和卸载装备的特效无法被无效化，可能会出现换过去的时候触发，换回来的时候不触发的场面（先村寄耦摆）
--------------------------------------------------

-- local v_fushen_invalidity = fk.CreateInvaliditySkill {
--   name = "#v_fushen_invalidity",
--   invalidity_func = function(self, from, skill)
--     return (from:getMark("@@v_fushen_target") > 0
--       and not skill.attached_equip)
--   end
-- }

-- local v_fushen = fk.CreateTriggerSkill{
--   --（刚需）技能认证名
--   name = "v_fushen",
--   --(非必要）赋予特殊型技能定义
--   anim_type = "special",
--   mute = true,
--   frequency = Skill.Limited,
--   --时机：阶段开始时，阶段变化时
--   events = {fk.EventPhaseStart,fk.EventPhaseEnd,fk.EventPhaseChanging},
--   --触发条件：
--   --（通用）触发时机的角色为遍历到的角色（已完成）
--   --（阶段开始时）遍历到的角色处于Notactive阶段、遍历到的角色存在invoke标记、（已完成）
--   --             遍历到的角色不处于extra_turn
--   --             （目前做不到，建议以后触发额外回合的时候做个额外mark陪着···）。
--   --（阶段变化时）遍历到的角色存在invoking标记、遍历到的角色处于Notactive阶段。
--   --（阶段变化时）遍历到的角色尚未使用过技能、遍历到的角色将进入出牌阶段、遍历到的角色存在出牌阶段。（已完成）
--   can_trigger = function(self, event, target, player, data)
--     if not (target == player and player:hasSkill(self)) then return false end
--     if event == fk.EventPhaseStart then
--       return player.phase == Player.NotActive and player:getMark("v_fushen_invoke") > 0
--     elseif event == fk.EventPhaseEnd then
--       return 
--         player:getMark("v_fushen_invoking") > 0 
--         and player.phase == Player.Finish
--     elseif event == fk.EventPhaseChanging then
--       return
--         player:usedSkillTimes(self.name, Player.HistoryGame) == 0 
--         and data.to == Player.Play and VslUtil.exist_or_not(player, Player.Play)
--     end
--   end,
--   --使用条件：（已完成）
--   --（阶段开始时）消除invoke标记，给定范围，选择玩家，如果存在，return true。
--   --（阶段结束时）return true。
--   --（阶段变化时）askforskillinvoke。
--   on_cost = function(self, event, target, player, data)
--     local room = player.room
--     if event == fk.EventPhaseStart then
--       room:setPlayerMark(player, "v_fushen_invoke", 0)
--       local targets = {}
--       for _, p in ipairs(room:getOtherPlayers(player)) do
--         --后续可以在这里筛选caneffect角色。
--         table.insert(targets, p.id)
--       end

--       if #targets > 0 then
--         local to = room:askForChoosePlayers(player, targets, 1, 1, "#v_fushen_target_choose", self.name, false)[1]
--         if to then
--           self.cost_data = to
--           return true
--         end
--       end
--     elseif event == fk.EventPhaseEnd then
--       return true
--     elseif event == fk.EventPhaseChanging then
--       if room:askForSkillInvoke(player, self.name, data) then
--         return true
--       end
--     end
--   end,
--   --使用效果：
--   --（阶段开始时）发送附身信息等；换位置；获得对方技能；获得额外回合；
--   -- PS:这个阶段你要是把对面扬了，直接报错，然后这个角色没了，但你依然可以打她。
--   --（阶段结束时）发送结束附身信息；换回来；
--   --（阶段变化时）失去附身未使用标记；获得invoke标记；跳过出牌阶段。
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     if event == fk.EventPhaseStart then
--       local to = room:getPlayerById(self.cost_data)
--       room:setPlayerMark(player, "v_fushen_to", self.cost_data)
--       room:setPlayerMark(player, "v_fushen_invoking", 1)
--       local skills = {}
--       room:sendLog{
--         type = "#v_fushen_log",
--         from = player.id,
--         to = {to.id},
--         arg = self.name,
--       }
--       --这里看情况决定要不要写指示线
--       if player ~= to then
--         --doindicate的两个参数均为integer类型，一般为角色id
--         room:doIndicate(player.id, { to.id })
--       end
--       room:notifySkillInvoked(player, self.name)
--       VslUtil.swap_player(player, player, to, self.name, true)
--       room:setPlayerMark(player, "@@v_fushen_using", 1)
--       room:setPlayerMark(to, "@@v_fushen_target", 1)
--       for _, skill_name in ipairs(to.player_skills) do
--         -- print(skill_name) --这步没问题
--         -- print(skill_name.lordSkill)
--         -- print(skill_name.frequency)
--         if (
--           (not skill_name.lordSkill)
--           and (skill_name.frequency ~= Skill.Limited) 
--           and (skill_name.frequency ~= Skill.Wake)
--           and not skill_name.attached_equip
--           ) 
--           and not table.find(player.player_skills, 
--           function(skill_name_player)
--             return skill_name_player == skill_name
--           end
--         ) then
--           -- print(skill_name)
--           table.insertIfNeed(skills, skill_name.name)
--         end
--       end
--       if #skills > 0 then
--         room:setPlayerMark(player, "v_fushen_skills", skills)
--         room:handleAddLoseSkills(player, table.concat(skills, "|"), nil, true, false)
--       end
--       player:gainAnExtraTurn()
--     elseif event == fk.EventPhaseEnd then
--       room:setPlayerMark(player, "v_fushen_invoking", 0)
--       local to = room:getPlayerById(player:getMark("v_fushen_to"))
--       room:sendLog{
--         type = "#v_fushen_end_log",
--         from = player.id,
--         to = {to.id},
--         arg = self.name,
--       }
--       if to:isAlive() and player:isAlive() then
--         VslUtil.swap_player(player, player, to, self.name, true)
--       else
--         room:swapSeat(player, to)
--       end
--       room:setPlayerMark(player, "@@v_fushen_using", 0)
--       room:setPlayerMark(to, "@@v_fushen_target", 0)
--       local skills = player:getMark("v_fushen_skills")
--       room:setPlayerMark(player, "v_fushen_skills", 0)
--       if skills ~= 0 and #skills > 0 then
--         room:handleAddLoseSkills(player, "-"..table.concat(skills, "|-"), nil, true, false)
--       end
--     elseif event == fk.EventPhaseChanging then
--       room:setPlayerMark(player, "@@v_fushen", 0)
--       room:setPlayerMark(player, "v_fushen_invoke", 1)
--       return true
--     end
--   end,
-- }

-- v_fushen:addRelatedSkill(v_fushen_invalidity)

--------------------------------------------------
--附身测试
--这一版的技能建议多关注一下孔雀天帝的技能，希望他们哪天把Self优化了，就可以不用村规啦。
--变相自带AK，削弱方案：1. 每种牌名限一次（需要qmlmark辅助）；2. 出牌阶段限制若干次（例如根据当前体力）；3. 指定本回合未造成伤害的角色
--------------------------------------------------

local v_fushen = fk.CreateActiveSkill{
  name = "v_fushen",
  anim_type = "control",
  prompt = "#v_fushen-active",
  can_use = function(self, player)
    return player:getMark("v_fushen_prohibit-phase") == 0
      and player:usedSkillTimes(self.name, Player.HistoryPhase) < (player:getLostHp() + 1)
      -- and VslUtil.is_wounded(player)

    -- 一旦后续内存出问题了，把下面的所有代码统统注释掉，用最上面这一行代码，走村规。
    -- 好吧暂时用不到了，因为不明原因这段代码废了
    -- local room = Fk:currentRoom()
    -- for _, cid in ipairs(player:getCardIds(Player.Hand)) do
    --   local card = Fk:getCardById(cid)
    --   if card.id <= 0 then return false end
    --   for _, pp in ipairs(room.alive_players) do
    --     local u = false
    --     if pp.id ~= player:getMark("v_fushen_p") 
    --       and pp:canUse(card) and not pp:prohibitUse(card)
    --       and card.id > 0 then
    --         u = true
    --     end
    --     return u
    --   end
    -- end
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id and Fk:currentRoom():getPlayerById(to_select):getMark("v_fushen_damaged-turn") == 0
  end,
  target_num = 1,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = effect.tos[1]
    room:addPlayerMark(player, "@v_fushen_times-phase", 1)
    room:setPlayerMark(player, "v_fushen_prohibit-phase", 1)
    room:setPlayerMark(player, "v_fushen_target", target)
    local general_info = {player.general, player.deputyGeneral}
    local tar_player = room:getPlayerById(target)
    room:setPlayerMark(tar_player, "@@v_fushen_target", 1)
    player.general = tar_player.general
    player.deputyGeneral = tar_player.deputyGeneral
    room:broadcastProperty(player, "general")
    room:broadcastProperty(player, "deputyGeneral")
    local _, ret = room:askForUseActiveSkill(player, "v_fushen_use", "#v_fushen-use::" .. target, true)
    room:setPlayerMark(player, "v_fushen_target", 0)
    player.general = general_info[1]
    player.deputyGeneral = general_info[2]
    room:broadcastProperty(player, "general")
    room:broadcastProperty(player, "deputyGeneral")
    if ret then
      room:useCard({
        from = target,
        tos = table.map(ret.targets, function(pid) return { pid } end),
        card = Fk:getCardById(ret.cards[1]),
      })
    end
  end,
}
local v_fushen_refresh = fk.CreateTriggerSkill{
  name = "#v_fushen_refresh",
  refresh_events = {fk.PreCardUse
    -- , fk.EventAcquireSkill, fk.EventLoseSkill
  },
  can_refresh = function(self, event, target, player, data)
    if event == fk.PreCardUse then
      return player:getMark("v_fushen_prohibit-phase") > 0
    -- elseif event == fk.EventAcquireSkill then
    --   return target == player and player:getMark("v_fushen_p") == 0
    -- elseif event == fk.EventLoseSkill then
    --   return target == player and player:getMark("v_fushen_p") > 0
    end
  end,
  on_refresh = function(self, event, target, player, data)
    if event == fk.PreCardUse then
      player.room:setPlayerMark(player, "v_fushen_prohibit-phase", 0)
    -- elseif event == fk.EventAcquireSkill then
    --   player.room:setPlayerMark(player, "v_fushen_p", player.id)
    -- elseif event == fk.EventLoseSkill then
    --   player.room:setPlayerMark(player, "v_fushen_p", 0)
    end
  end,
}
local v_fushen_use = fk.CreateActiveSkill{
  name = "v_fushen_use",
  card_filter = function(self, to_select, selected)
    if #selected > 0 then return false end
    local room = Fk:currentRoom()
    if room:getCardArea(to_select) == Card.PlayerEquip then return false end
    local target_id = Self:getMark("v_fushen_target")
    local target = room:getPlayerById(target_id)
    local card = Fk:getCardById(to_select)
    return target:canUse(card) and not target:prohibitUse(card)
      and card.id > 0
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if #selected_cards ~= 1 then return false end
    local card = Fk:getCardById(selected_cards[1])
    local card_skill = card.skill
    local room = Fk:currentRoom()
    local target_id = Self:getMark("v_fushen_target")
    local target = room:getPlayerById(target_id)
    if card_skill:getMinTargetNum() == 0 or #selected >= card_skill:getMaxTargetNum(target, card) then return false end
    return not target:isProhibited(room:getPlayerById(to_select), card) and
      card_skill:modTargetFilter(to_select, selected, target_id, card, true)
  end,
  feasible = function(self, selected, selected_cards)
    if #selected_cards ~= 1 then return false end
    local card = Fk:getCardById(selected_cards[1])
    local card_skill = card.skill
    local room = Fk:currentRoom()
    local target_id = Self:getMark("v_fushen_target")
    local target = room:getPlayerById(target_id)
    return #selected >= card_skill:getMinTargetNum() and #selected <= card_skill:getMaxTargetNum(target, card)
  end,
}
Fk:addSkill(v_fushen_use)
v_fushen:addRelatedSkill(v_fushen_refresh)

--------------------------------------------------
--灵虚
--"你的手牌上限 + x/2（x为成为过“附身”目标且在场的角色数，向上取整）。"
--------------------------------------------------

local v_lingxu = fk.CreateMaxCardsSkill{
  name = "v_lingxu",
  correct_func = function(self, player)
    if player:hasSkill(self.name) then
      local n = 0
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if p:getMark("@@v_fushen_target") == 1 then
          n = n + 1
        end
      end
      return math.ceil(n / 2.0)
    end
    return 0
    -- return - player:getMark("hf__huilei_temp")
  end,
}

--------------------------------------------------
--夕兔
--------------------------------------------------

local xitu_duoshelingtu = General(extension, "xitu_duoshelingtu", "keasofer", 3, 3, General.Female)
xitu_duoshelingtu:addSkill(v_yingji)
xitu_duoshelingtu:addSkill(v_fushen)
xitu_duoshelingtu:addSkill(v_lingxu)
-- xitu_duoshelingtu:addSkill(v_fushen2)

--------------------------------------------------
--幽蓝
--技能马克：缺少七海表情包
--------------------------------------------------

local v_youlan = fk.CreateTriggerSkill{
  --（刚需）技能认证名
  name = "v_youlan",
  --(非必要）赋予特殊型技能定义
  anim_type = "special",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  --时机：受到伤害时，造成伤害时
  events = {fk.DamageInflicted,fk.DamageCaused},
  --触发条件：
  --（受到伤害时）触发时机的角色为遍历到的角色、遍历到的角色具有本技能、牌为实体牌、牌的种类为锦囊牌、造成的伤害大于0。
  --（造成伤害时）造成伤害的来源为遍历到的角色、遍历到的角色具有本技能、牌为实体牌、牌的种类为锦囊牌、造成的伤害大于0。
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      (data.card and data.card.type == Card.TypeTrick)  and data.damage > 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.DamageInflicted then
      local address = "./packages/"..VslUtil.extensionName.."/image/skill/qihaiyouxian_2"
      room:setEmotion(player, address)
      data.damage = data.damage - 1
      if data.damage <= 0 then
        address = "./packages/"..VslUtil.extensionName.."/image/anim/skill_nullify"
        room:setEmotion(player, address)
      end
    elseif event == fk.DamageCaused then
      local address = "./packages/"..VslUtil.extensionName.."/image/skill/qihaiyouxian_1"
      room:setEmotion(player, address)
      data.damage = data.damage + 1
    end
  end,
}

--------------------------------------------------
--角色特性：箭雨（七海幽娴）
--------------------------------------------------

local v_characteristic_jianyu_qihaiyouxian = fk.CreateTriggerSkill{
  name = "#v_characteristic_jianyu_qihaiyouxian",
  anim_type = "special",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  events = {fk.GameStart},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self.name, true) then
      return false
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      local cids = {}
      -- for i = #room.void, 1, -1 do
      --   if Fk:getCardById(room.void[i]).name == "raid_and_frontal_attack" then
      --     local idRemoved = table.remove(room.void, i)
      --     table.insert(room.draw_pile, math.random(1, #room.draw_pile), idRemoved)
      --     room:setCardArea(idRemoved, Card.DrawPile, nil)
      --   end
      -- end
      local card = room:printCard("archery_attack", Card.Heart, 7)
      table.insertIfNeed(cids, card.id)
      local ram = math.random(1, #room.draw_pile + 1)
      room:moveCards({
        ids = cids,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonJustMove,
        skillName = self.name,
        drawPilePosition = ram,
      })
      room:sendLog{
				type = "#v_newcardintopile_log",
				from = player.id,
				card = cids,
				arg = self.name,
			} 
      room:doBroadcastNotify("UpdateDrawPile", #room.draw_pile)
    end
  end,
}

--------------------------------------------------
--七海幽娴
--角色马克：幽蓝，特性·箭雨未实装
--------------------------------------------------

local qihaiyouxian_zhuangzhilingyun = General(extension, "qihaiyouxian_zhuangzhilingyun", "VirtualDove", 4, 3, General.Agender)
qihaiyouxian_zhuangzhilingyun:addSkill(v_youlan)
-- qihaiyouxian_zhuangzhilingyun:addSkill(v_characteristic_jianyu_qihaiyouxian)

--------------------------------------------------
--险至
--------------------------------------------------

local v_xianzhi_prohibit = fk.CreateProhibitSkill{
  name = "#v_xianzhi_prohibit",
  prohibit_use = function(self, player, card)
    if player:getMark("@@v_xianzhi-turn") ~= 0 and card then
      return card.type == Card.TypeBasic
    end   
  end,
  prohibit_response = function(self, player, card)
    if player:getMark("@@v_xianzhi-turn") ~= 0 and card then
      return card.type == Card.TypeBasic
    end 
  end,
}
local v_xianzhi = fk.CreateTriggerSkill{
  name = "v_xianzhi",
  anim_type = "control",
  events ={fk.TargetSpecified,fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    -- if not (player == target and player:hasSkill(self)) then
    --   return false
    -- end
    local room = player.room
    if event == fk.TargetSpecified then
      if player == target and player:hasSkill(self)
        and data.card
        and (data.card.trueName == "slash" or data.card.name == "duel")
        and #AimGroup:getAllTargets(data.tos) == 1
      then
        local to = room:getPlayerById(data.to)
        local datatos = 
          -- (not to:isNude()) or 
          (not (to:getMark("@@v_xianzhi-turn") > 0))
        return datatos
      end
    elseif event == fk.CardUseFinished then
      return 
        data.card
        and data.card:getMark("v_xianzhi-turn") == player.id
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.CardUseFinished then
      return true
    else
      return player.room:askForSkillInvoke(player,self.name)
    end 
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecified then  
      local to = room:getPlayerById(data.to)  
      --这里看情况决定要不要写指示线
      if player ~= to then
        --doindicate的两个参数均为integer类型，一般为角色id
        room:doIndicate(player.id, { to.id })
      end 
      local choiceList = {}
      if not (to:getMark("@@v_xianzhi-turn") > 0) then
        table.insert(choiceList, "#v_xianzhi1") 
      end
      -- if not to:isNude() then
		  table.insert(choiceList, "#v_xianzhi2")
      -- end
      if choiceList ~= {} then
        local choice = room:askForChoice(to, choiceList, self.name)
        if choice == "#v_xianzhi1" then
          room:sendLog{
            type = "#v_choose",
            from = to.id,
            arg = "#v_xianzhi1",
            -- arg2 = data.damage,
          }
          room:setPlayerMark(to,"@@v_xianzhi-turn", 1)
        elseif choice == "#v_xianzhi2" then
          room:sendLog{
            type = "#v_choose",
            from = to.id,
            arg = "#v_xianzhi2",
            -- arg2 = data.damage,
          }
          room:setCardMark(data.card, "v_xianzhi-turn", to.id)
        end
      end
    elseif event == fk.CardUseFinished then
      room:setCardMark(data.card, "v_xianzhi-turn", 0)
      if (not player:isNude()) then
        room:askForDiscard(player, 1, 1, true, self.name, false,".", "v_discard_1")
      else
        room:sendLog{
          type = "#v_player_discard_fail",
          from = player.id,
          arg = self.name,
        }
      end
    end
  end,
}

v_xianzhi:addRelatedSkill(v_xianzhi_prohibit)

--------------------------------------------------
--冥邀
--------------------------------------------------

local v_mingyao_distance = fk.CreateDistanceSkill{
	name = "#v_mingyao_distance",
	correct_func = function(self, from, to) return 0 end,
	fixed_func = function(self, from, to)
		if to:getMark("@@v_mingyao-round") ~= 0 then
		  return 1
		end
	end,
}

local v_mingyao = fk.CreateTriggerSkill{
  name = "v_mingyao",
  anim_type = "control",
  events = {fk.RoundStart},
  frequency = Skill.Limited,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,

  on_cost = function(self, event, target, player, data)
    local room = player.room
    local fir_targets = table.map(room:getOtherPlayers(player), function(p) return p.id end)
    local targets = {}
    --这里后续可以加caneffect
    for _, pid in ipairs(fir_targets) do
      if VslUtil.SkillCanTarget(room:getPlayerById(pid), player, self.name) then
        table.insert(targets, pid)
      end
    end
    if #targets == 0 then return end
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#v_mingyao_choice", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end   
  end,

  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    room:setPlayerMark(to, "@@v_mingyao-round", 1)
  end,

  refresh_events = {fk.AfterDying},
  can_refresh = function(self, event, target, player, data)
    return event == fk.AfterDying and target == player and player:getMark("@@v_mingyao-round") ~= 0 
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:changeMaxHp(player, -1)
  end,
}

v_mingyao:addRelatedSkill(v_mingyao_distance)
  
--------------------------------------------------
--尼莫
--------------------------------------------------

local nimo_avatarofevil = General(extension, "nimo_avatarofevil", "individual", 4, 4, General.Female)
nimo_avatarofevil:addSkill(v_xianzhi)
nimo_avatarofevil:addSkill(v_mingyao)

--------------------------------------------------
--阳能
--------------------------------------------------

local v_yangneng = fk.CreateTriggerSkill{
  name = "v_yangneng",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  mute = true,
  events = {fk.BeforeCardsMove, fk.AfterCardsMove, fk.EventPhaseStart},
  --使用条件：（已完成）
  -- ...
  can_trigger = function(self, event, target, player, data)
    local room = player.room
    if event == fk.BeforeCardsMove then
      if room:getTag("FirstRound") then return false end
      for _, move in ipairs(data) do
        if move.toArea == Player.Hand
          and move.to
          and move.to == player.id
          and player
          and player.phase ~= Player.NotActive
          -- and #move.ids > 0 
        then
          return true
        end
      end
    elseif event == fk.AfterCardsMove then
      if room:getTag("FirstRound") then return false end
      for _, move in ipairs(data) do
        if move.skillName ~= self.name 
          and move.toArea == Player.Hand
          and move.to
          and move.to == player.id
          and (player and player:hasSkill(self))
          and player.phase == Player.NotActive
          -- and #move.ids > 0 
        then
          return true
        end
      end
    elseif event == fk.EventPhaseStart then
      return player == target and player:hasSkill(self)
        and player.phase == Player.Discard
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.BeforeCardsMove then
      for _, move in ipairs(data) do
        for _, info in ipairs(move.moveInfo) do
          local yangneng_card = Fk:getCardById(info.cardId)
          room:setPlayerMark(player,"v_yangneng_card_"..info.cardId.."-turn", 1)
          if player:hasSkill(self) then
            room:setCardMark(yangneng_card, "@@v_yangneng-cm!dc*", 1)
          end
        end
      end
    elseif event == fk.AfterCardsMove then
      room:delay(250)
      room:notifySkillInvoked(player, self.name)
      player:broadcastSkillInvoke(self.name)
      player:drawCards(1, self.name)
    elseif event == fk.EventPhaseStart then
      local return_ids = {}
      for _,cid in ipairs(player:getCardIds(Player.Hand)) do
        if player:getMark("v_yangneng_card_"..cid.."-turn") > 0 then
          room:setPlayerMark(player, "v_yangneng_card_"..cid.."-turn", 0)
          room:setCardMark(Fk:getCardById(cid), "@@v_yangneng-cm!dc*", 0)
          table.insertIfNeed(return_ids, cid)
        end
      end
      if #return_ids > 0 then
        room:notifySkillInvoked(player, self.name)
        player:broadcastSkillInvoke(self.name)
        VslUtil.return_draw_pile(player, return_ids, self.name)
        room:delay(300)
      end
    end
  end,
}

--------------------------------------------------
--阴憩
--------------------------------------------------

local v_yinqi = fk.CreateTriggerSkill{
  name = "v_yinqi",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted, fk.EventPhaseChanging},
  --使用条件：（已完成）
  -- ...
  can_trigger = function(self, event, target, player, data)
    if event == fk.DamageInflicted then
      return data.damage > 0 
      --  and data.from and data.to
       and player:isKongcheng()
       and player:hasSkill(self) and target == player
    elseif event == fk.EventPhaseChanging then
      return player == target and player:getMark("@v_yinqi") > 0
        and VslUtil.exist_or_not(player, Player.Draw) 
        and data.to == Player.Draw
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.DamageInflicted then
      player:drawCards(1, self.name)
      room:addPlayerMark(player, "@v_yinqi", 1)
      local address = "./packages/"..VslUtil.extensionName.."/image/anim/skill_nullify"
      room:setEmotion(player, address)
      return true
    elseif event == fk.EventPhaseChanging then
      room:removePlayerMark(player, "@v_yinqi", 1)
      player:skip(Player.Draw)
      return true
    end
  end,
}

--------------------------------------------------
--早凉
--------------------------------------------------

local zaoliang_jiqimao = General(extension, "zaoliang_jiqimao", "individual", 3, 3, General.Agender)
zaoliang_jiqimao:addSkill(v_yangneng)
zaoliang_jiqimao:addSkill(v_yinqi)

--------------------------------------------------
--撷芳
--------------------------------------------------

local v_xiefang = fk.CreateDistanceSkill{
  name = "v_xiefang",
  correct_func = function(self, from, to)
    if from:hasSkill(self) then
      local n = 0
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if p.gender == General.Female then
          n = n + 1
        end
      end
      return -n
    end
    return 0
  end,
}

--------------------------------------------------
--心动
--------------------------------------------------

local v_xindong = fk.CreateTriggerSkill{
  name = "v_xindong",
  anim_type = "drawcard",
  events = {fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
    and player.phase == Player.Play
  end,

  on_cost = function(self, event, target, player, data)
    local room = player.room
    local fir_targets = table.map(room:getOtherPlayers(player), function(p) return p.id end)
    local targets = {}
    --这里后续可以加caneffect
    for _, pid in ipairs(fir_targets) do
      if VslUtil.SkillCanTarget(room:getPlayerById(pid), player, self.name) and player:inMyAttackRange(room:getPlayerById(pid)) then
        table.insert(targets, pid)
      end
    end
    if #targets == 0 then return end
    local to = room:askForChoosePlayers(player, targets, 1, 3, "#v_xindong_choice", self.name, true)
    if #to > 0 then
      self.cost_data = to
      return true
    end   
  end,

  on_use = function(self, event, target, player, data)
    local room = player.room
    local tos = self.cost_data
    local to
    for _,pid in ipairs(tos) do
      to = room:getPlayerById(pid)
      room:drawCards(to, 1, self.name)
    end
    local maxcard = room:getPlayerById(tos[1]):getHandcardNum()
    local maxone = room:getPlayerById(tos[1])
    for _,pid in ipairs(tos) do
      if room:getPlayerById(pid):getHandcardNum() > maxcard then
        maxcard = room:getPlayerById(pid):getHandcardNum()
        maxone = room:getPlayerById(pid)
      end
    end
    local maxtime = 0
    for _,pid in ipairs(tos) do
      to = room:getPlayerById(pid)
      if to:getHandcardNum() == maxcard then
        maxtime = maxtime + 1
        maxone = to
      end
    end
    if maxtime == 1 then
      if maxone:getMark("@@v_xindong") == 0 then
        room:setPlayerMark(maxone, "@@v_xindong", 1)
        room:damage{
          to = maxone,
          damage = 1,
          damageType = fk.FireDamage,
          skillName = self.name,
        }
      end
    end
  end,
}

  
--------------------------------------------------
--雪狐桑
--------------------------------------------------

local xuehusang_zizaisuixin = General(extension, "xuehusang_zizaisuixin", "individual", 3, 3, General.Female)
xuehusang_zizaisuixin:addSkill(v_xiefang)
xuehusang_zizaisuixin:addSkill(v_xindong)

--------------------------------------------------
--琉彩
--------------------------------------------------

local v_liucai = fk.CreateTriggerSkill{
  name = "v_liucai",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.DrawNCards},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.DrawNCards then
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.DrawNCards then
      local all_suit = {"spade", "heart", "club", "diamond"}
      local dummy = Fk:cloneCard('slash', Card.NoSuit, 0)
      -- local draw_c = {}
      for _,cid in ipairs(player:getCardIds(Player.Hand)) do
        if table.contains(all_suit, Fk:getCardById(cid):getSuitString()) then
          table.removeOne(all_suit, Fk:getCardById(cid):getSuitString())
        end
      end
      if #all_suit > 0 then
        local heart_cards = {}
				local diamond_cards = {}
				local spade_cards = {}
				local club_cards = {}
        for _,cid in ipairs(room.draw_pile) do
          local c = Fk:getCardById(cid)
            if table.contains(all_suit, c:getSuitString()) then
              if c.suit == Card.Spade then
                table.insert(spade_cards, c)
              elseif c.suit == Card.Club then
                table.insert(club_cards, c)
              elseif c.suit == Card.Heart then
                table.insert(heart_cards, c)
              elseif c.suit == Card.Diamond then
                table.insert(diamond_cards, c)
              end
            end
        end
        if #heart_cards > 0 then
          dummy:addSubcard(heart_cards[math.random(1, #heart_cards)])
        end
        if #diamond_cards > 0 then
          dummy:addSubcard(diamond_cards[math.random(1, #diamond_cards)])
        end
        if #spade_cards > 0 then
          dummy:addSubcard(spade_cards[math.random(1, #spade_cards)])
        end
        if #club_cards > 0 then
          dummy:addSubcard(club_cards[math.random(1, #club_cards)])
        end
        table.shuffle(dummy.subcards)
        if #dummy.subcards > 0 then
          --这段如果后续改为不公开，log就不要展示了直接删掉。
          room:sendLog{
            type = "#v_liucai_log",
            from = player.id,
            arg = self.name,
            card = dummy.subcards,
          }
          room:obtainCard(player, dummy, true)
        end
      end
      data.n = 0
    end
  end,
}

--------------------------------------------------
--守惑
--------------------------------------------------

Fk:addPoxiMethod{
  name = "v_shouhuo_discard",
  card_filter = function(to_select, selected, data, extra_data)
    local cards1 = extra_data[1]
    local cards2 = extra_data[1]
    local hand = table.contains(cards1, to_select)
    local equip = table.contains(cards2, to_select)
    local area = true
    for i = 1,#selected do
      if hand then
        if table.contains(cards1, selected[i]) then
          area = false
        end
      elseif equip then
        if table.contains(cards2, selected[i]) then
          area = false
        end
      end
    end
    return area and not Self:prohibitDiscard(Fk:getCardById(to_select))
  end,
  feasible = function(selected, data)
    --这东西相当于 选了几个区域的牌弃置几张，没办法做到两个区域的话必须弃置两张
    if #selected < 1 or #selected > 2 then return false end
    local areas = {}
    for _, v in ipairs(data) do
      if #v[2] > 0 then
        table.insertIfNeed(areas, v[2])
      end
    end
    return #areas == #selected
  end,
  prompt = function ()
    return Fk:translate("#v_shouhuo_detail")
  end
}

local v_shouhuo = fk.CreateTriggerSkill{
  name = "v_shouhuo",
  anim_type = "drawcard",
  events = {fk.EventPhaseStart, fk.EventPhaseChanging},
  --使用条件：（已完成）
  -- ...
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return player:hasSkill(self) and target == player
        and player.phase == Player.Finish
        and player:getMark("@@v_shouhuo-turn") > 0
        and not player:isAllNude()
    elseif event == fk.EventPhaseChanging then
      return player == target and player:hasSkill(self)
        and VslUtil.exist_or_not(player, Player.Discard) 
        and data.to == Player.Discard
        and not player:isAllNude()
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      return true
    elseif event == fk.EventPhaseChanging then
      local prompt = "#v_shouhuo_choice"
      if room:askForSkillInvoke(player, self.name, data, prompt) then
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      room:setPlayerMark(player, "@@v_shouhuo-turn", 0)
      local cards1 = player:getCardIds("h")
      local cards2 = player:getCardIds("e")
      local cards = room:askForPoxi(player, "v_shouhuo_discard", {
        { VslUtil.area_type["hand"], cards1 },
        { VslUtil.area_type["equip"], cards2 },
      }, {cards1, cards2}, false)
      local moveInfos = {}
      if #cards > 0 then
        table.insert(moveInfos, {
          from = player.id,
          ids = cards,
          toArea = Card.DiscardPile,
          moveReason = fk.ReasonDiscard,
          proposer = player.id,
          skillName = self.name,
        })
      end
      room:moveCards(table.unpack(moveInfos))
    elseif event == fk.EventPhaseChanging then
      room:setPlayerMark(player, "@@v_shouhuo-turn", 1)
      player:skip(Player.Discard)
      return true
    end
  end,
}

--------------------------------------------------
--星月璃り
--------------------------------------------------

local xingyueli_gulvguixing = General(extension, "xingyueli_gulvguixing", "individual", 4, 4, General.Female)
xingyueli_gulvguixing:addSkill(v_liucai)
xingyueli_gulvguixing:addSkill(v_shouhuo)

--------------------------------------------------
--翩翩
--转换技：0为阳（白），1为阴（黑）
--------------------------------------------------

local v_pianpian = fk.CreateTriggerSkill{
  name = "v_pianpian",
  switch_skill_name = "v_pianpian",
  anim_type = "switch",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if not (target == player and player:hasSkill(self) and
      player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and
      player:getHandcardNum() < player:getGeneralMaxHp()) then return end

    local isYang = player:getSwitchSkillState(self.name) == fk.SwitchYang
    if player.phase == Player.Finish and isYang then
      return true
    elseif player.phase == Player.Start and not isYang then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local isYang = player:getSwitchSkillState(self.name) == fk.SwitchYang
    player:drawCards(1, self.name)
    room:setPlayerMark(player, "@@v_pianpian-turn", 1)
    if isYang then
      room:setPlayerMark(player, "@v_pianpian_state", "O")
    elseif not isYang then
      room:setPlayerMark(player, "@v_pianpian_state", 1)
    end
  end,
}

--------------------------------------------------
--寄月
--------------------------------------------------

local v_jiyue = fk.CreateActiveSkill{
  name = "v_jiyue",
  anim_type = "special",
  min_target_num = function(self)
    if self.interaction.data == "v_jiyue_4" then
      return 1
    elseif self.interaction.data == "v_jiyue_23" then
      return 0
    end
  end,
  max_target_num = 1,
  min_card_num = function(self)
    if self.interaction.data == "v_jiyue_4" then
      return 4
    elseif self.interaction.data == "v_jiyue_23" then
      return 2
    end
  end,
  max_card_num = function(self)
    if self.interaction.data == "v_jiyue_4" then
      return 4
    elseif self.interaction.data == "v_jiyue_23" then
      return 3
    end
  end,
  interaction = function(self)
    local v_jiyue_choice = {"v_jiyue_23"}
    if Self:getHandcardNum() + #Self:getCardIds(Player.Equip) >= 4 then
      table.insert(v_jiyue_choice, "v_jiyue_4")
    end
    return UI.ComboBox {
      choices = v_jiyue_choice
    } 
  end,
  can_use = function(self, player)
    return 
      player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and 
      not player:isNude()
  end,
  card_filter = function(self, to_select, selected, targets)
    if self.interaction.data == "v_jiyue_4" then
      return #selected == 0 or 
      (#selected > 0 and #selected < 4 and Fk:getCardById(to_select).trueName == Fk:getCardById(selected[1]).trueName)
    elseif self.interaction.data == "v_jiyue_23" then
      return #selected == 0 or 
      (#selected > 0 and #selected < 3 and Fk:getCardById(to_select).trueName == Fk:getCardById(selected[1]).trueName)
    end

  end,
  target_filter = function(self, to_select, selected)
    if self.interaction.data == "v_jiyue_4" then
      --这里后续可以加caneffect
      return #selected == 0
    elseif self.interaction.data == "v_jiyue_23" then
      return false
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target
    if #effect.tos > 0 then
      target = room:getPlayerById(effect.tos[1])
    end
    if #effect.cards > 0 then
      VslUtil.return_draw_pile(player, effect.cards, self.name)
    end
    if #effect.cards < 4 then
      local allCardIds = Fk:getAllCardIds()
      local allCardMapper = {}
      local allCardNames = {}
      local cardType
      if #effect.cards == 2 then
        cardType = Card.TypeBasic
      elseif #effect.cards == 3 then
        cardType = Card.TypeTrick
      end
      --这段写法感觉可以考虑再优化下···
      --例如用getallcardnames获取加入游戏的卡的牌名，等到选择好了再去找对应的牌···
      for _, id in ipairs(allCardIds) do
        local card = Fk:getCardById(id)
        if card.type == cardType then
          if allCardMapper[card.name] == nil then
            table.insert(allCardNames, card.name)
          end
          allCardMapper[card.name] = allCardMapper[card.name] or {}
          if table.contains(room.draw_pile, id) then
            table.insert(allCardMapper[card.name], id)
          end
        end
      end

      if #allCardNames == 0 then
        return
      end

      local cardName = room:askForChoice(player, allCardNames, self.name)
      local toGain
      if #allCardMapper[cardName] > 0 then
        toGain = allCardMapper[cardName][math.random(1, #allCardMapper[cardName])]
        room:obtainCard(effect.from, toGain, true, fk.ReasonPrey)
      end

    elseif #effect.cards == 4 then
      player:turnOver()
      room:damage({
        from = player,
        to = target,
        damage = 3,
        damageType = fk.FireDamage,
        skillName = self.name,
      })
    end
  end,
}

--------------------------------------------------
--扇宝
--------------------------------------------------

local shanbao_fengyaliangyou = General(extension, "shanbao_fengyaliangyou", "individual", 3, 3, General.Female)
shanbao_fengyaliangyou:addSkill(v_pianpian)
shanbao_fengyaliangyou:addSkill(v_jiyue)

--------------------------------------------------
--福音
--------------------------------------------------

Fk:addQmlMark{
  name = "v_fuyin_shayue",
  qml_path = function(name, value, p)
    return "packages/"..VslUtil.extensionName.."/qml/VFuyinShayueBox"
  end,
  how_to_show = function(name, value, p)
    if type(value) == "table" and type(value[1]) == "table" then
      return tostring(#value[1])
    end
    return " "
  end,
}

local v_fuyin_shayue = fk.CreateTriggerSkill{
  name = "v_fuyin_shayue",
  -- mute = true,
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target and target.hp < 1
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name)
      and VslUtil.SkillCanTarget(target, player, self.name)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local judge_times = 1
    local judge_result = true
    local cids = {}
    local no_mark = {}
    if target ~= player then
      judge_times = 2
    end
    for times = 1, judge_times, 1 do
      local yes_table = {1,2,3,4,5,6,7,8,9,10,11,12,13}
      for i = 1,13,1 do
        local yes = true
        local mark = player:getMark("@[v_fuyin_shayue]")
        local no_table
        if type(mark) == "table" then
          no_table = player:getMark("@[v_fuyin_shayue]")[1]
          if type(no_table) == "table" and table.contains(no_table, i) then
            yes = false
          end
        end  
        if not yes then
          table.removeOne(yes_table, i)
        end
      end
      local yes_str = table.concat(yes_table, ",")
      local judge = {
        who = target,
        reason = self.name,
        pattern = ".|"..yes_str,
      }
      room:judge(judge)
      if not table.contains(yes_table, judge.card.number) then
        judge_result = false
      end
      table.removeOne(yes_table, judge.card.number)
      
      for i = 1, 13, 1 do
        if not table.contains(yes_table, i) then
          table.insertIfNeed(no_mark, i)
        end
      end
      local no_str = table.concat(no_mark, ",")
      room:setPlayerMark(player, "@[v_fuyin_shayue]", {no_mark, no_str})
      --print(no_str)
      if room:getCardArea(judge.card.id) == Card.DiscardPile then
        table.insertIfNeed(cids, judge.card.id)
      end
    end
    if judge_result then
      room:recover{
        who = target,
        num = 1,
        recoverBy = player,
        skillName = self.name
      }
    else
      if #cids > 1 then
        local to_return = table.random(cids, 1)
        local choice = "confirm"
        local result = room:askForCustomDialog(player, self.name,
        "packages/utility/qml/ChooseCardsAndChoiceBox.qml", {
          cids,
          {"confirm"},
          "#v_fuyin_shayue_choice",
          {},
          1,
          1,
        })
        if result ~= "" then
          local reply = json.decode(result)
          to_return = reply.cards
          choice = reply.choice
        end
        if to_return[1] and to_return[1] ~= -1 then
          room:obtainCard(player, Fk:getCardById(to_return[1]), false, fk.ReasonPrey)
        end
      else
        room:obtainCard(player, Fk:getCardById(cids[1]), false, fk.ReasonPrey)
      end
    end
  end,
}

--------------------------------------------------
--维留
--------------------------------------------------

local v_weiliu = fk.CreateTriggerSkill{
  name = "v_weiliu",
  anim_type = "control",
  events = {fk.AskForRetrial},
  can_trigger = function(self, event, target, player, data)
    local trigger = false
    local allcids = {}
    local hand = player:getCardIds(Player.Hand)
    local equip = player:getCardIds(Player.Equip)
    table.insertTableIfNeed(allcids, hand)
    table.insertTableIfNeed(allcids, equip)
    for _,cid in ipairs(allcids) do
      if Fk:getCardById(cid).type == Card.TypeEquip then
        trigger = true
        break
      end
    end
    return player:hasSkill(self) and trigger
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "#v_weiliu_choice:"..data.who.id.."::"..self.name..":"..data.reason
    local card = room:askForCard(player, 1, 1, true, self.name, true, ".|.|.|.|.|equip", prompt)
    if #card > 0 then
      self.cost_data = card[1]
    return true
    end
  end,
  on_use = function(self, event, target, player, data)
    player.room:retrial(Fk:getCardById(self.cost_data), player, data, self.name, true)
  end,
}

--------------------------------------------------
--沙月
--------------------------------------------------

local shayue_fanqietianshi = General(extension, "shayue_fanqietianshi", "individual", 3, 3, General.Bigender)
shayue_fanqietianshi:addSkill(v_fuyin_shayue)
shayue_fanqietianshi:addSkill(v_weiliu)


--冰契
--技能马克：最佳时机为damageforseen，目前就用这俩时机；初步已写完，保险起见暂时隐藏本角色及本技能。
--技能描述：根据原Vup杀1.0.0.1版本，如果出现两个本技能持有者同场且全场（超过两人）均横置：
--①下家B攻击持有本技能的A，由A控制本次冰杀（其被视为伤害来源优先触发）
--②B攻击A以外任意角色，选择弃牌，铁索不解除，伤害不传导。
--②B攻击A以外任意角色，选择伤害，铁索解除，后续无论弃牌与否均传导。顺序为起始伤员-当前回合逆时针（从B开始算）
--------------------------------------------------

local v_bingqi = fk.CreateTriggerSkill{
  --（刚需）技能认证名
  name = "v_bingqi",
  --(非必要）赋予特殊型技能定义
  anim_type = "special",
  mute = true,
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  --时机：伤害结算前
  -- events = {fk.DamageInflicted,fk.DamageCaused},
  events = {fk.PreDamage},
  -- events = {fk.DamageInflicted, fk.PreDamage},
  --触发条件：
  --（通用）触发时机的角色为遍历到的角色、遍历到的角色具有本技能、造成的伤害大于0，造成的伤害不为冰属性伤害。
  --（受到伤害时）牌为实体牌、牌的种类为锦囊牌、造成的伤害大于0。
  --（造成伤害时）造成伤害的来源为遍历到的角色、遍历到的角色具有本技能、牌为实体牌、牌的种类为锦囊牌、造成的伤害大于0。
  can_trigger = function(self, event, target, player, data)
    return 
      -- (data.from and data.from:hasSkill(self)) 
      -- or (data.to and data.to:hasSkill(self))
      -- and target == player
      (player == target or player == data.to)
      and player:hasSkill(self)
      and data.damage > 0 and data.damageType ~= fk.IceDamage
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player == data.to then
      data.from = data.to
    end
    data.damageType = fk.IceDamage
    room:sendLog{
      type = "#v_bingqi_log",
      from = data.from.id,
      --log.to是数组
      to = {data.to.id},
      arg = self.name,
      arg2 = data.damage,
    }
  end,
}

--------------------------------------------------
--灵窟
--FIXME:逃课解决了非基本牌的问题，但存在无法取消的问题，请期待新月杀新版本。
--------------------------------------------------

local v_lingku = fk.CreateActiveSkill{
  name = "v_lingku",
  mute = true,
  anim_type = "special",
  --使用条件：
  -- 本回合只使用过一次技能；
  -- （待补充）对方可以被技能指定为目标，技能可以对对方生效。
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  target_num = 1,
  card_filter = function(self, to_select, selected, selected_targets)
    return false
  end,
  --目标选择：
  -- 选定角色数量为0，选定角色不为自己，选定角色的手牌数>=3；
  target_filter = function(self, to_select, selected)
    local target = Fk:currentRoom():getPlayerById(to_select)
    local player = Fk:currentRoom().current
    return #selected == 0 and to_select ~= Self.id and target:getHandcardNum() >= 3
      and VslUtil.SkillCanTarget(target, player, self.name)
  end,
  --on_use内可以先加一个skillnullify的判定用来配合偷梁换柱和精算等技能无效化的东西
  -- （也希望这东西后续有更多优化吧）
  on_use = function(self, room, effect)
    --先随机选择对方三张手牌，根据是否为基本牌分门别类放好
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local ids = {}
    local show_ids = {}
    local cannot_choose_ids = {}
    local hand = target:getCardIds(Player.Hand)
    room:doAnimate("InvokeSkill", {
      name = self.name,
      player = player.id,
      skill_type = self.anim_type,
    })
    room:sendLog{
      type = "#v_skill_target",
      from = player.id,
      arg = self.name,
      to = { target.id }
    }
    player:broadcastSkillInvoke(self.name) --这个后续看效果 待定。
    for _,cd in ipairs(hand) do
      table.insert(ids, cd)
    end
    -- local foot_notes = {}
    while #show_ids < 3 do
      local random_one = table.random(ids)
      table.insert(show_ids, random_one)
      table.removeOne(ids, random_one)
      -- table.insert(foot_notes, target.general.."+hand_area")
      local ramcad = Fk:getCardById(random_one)
      if ramcad.type ~= Card.TypeBasic then
        table.insert(cannot_choose_ids, random_one)
      end
    end
    --进入观看牌的环节
    if #show_ids == 3 then
      -- room:fillAG(player, show_ids, cannot_choose_ids)
      --挣扎一下，但这玩意今天晚上玩下来感觉不太好。
      local to_return = table.random(show_ids, 1)
      local choice = "cancel"
      local result = room:askForCustomDialog(player, self.name,
      "packages/utility/qml/ChooseCardsAndChoiceBox.qml", {
        show_ids,
        {"confirm"},
        "#v_lingku_choice",
        {"cancel"},
        1,
        1,
        cannot_choose_ids,
      })
      if result ~= "" then
        local reply = json.decode(result)
        to_return = reply.cards
        choice = reply.choice
      end
      if to_return[1] and to_return[1] ~= -1 then
        --展示牌
        target:showCards(to_return[1])
        --摸牌
        --记录牌堆的同名牌。
        local can_get_ids = {}
        --这里没摸到牌堆/弃牌堆的牌
        local draw = room.draw_pile
        for _,p in ipairs(draw) do
          local card = Fk:getCardById(p)
          local idcard = Fk:getCardById(to_return[1])
          if card.name == idcard.name then
            table.insert(can_get_ids, p)
          end
        end
        if #can_get_ids > 0 then
          room:delay(500)
          local card_id = table.random(can_get_ids)
          room:obtainCard(target, Fk:getCardById(card_id), true, fk.ReasonPrey)
        else
          room:sendLog{
            type = "#v_player_find_fail",
            from = player.id,
            arg = self.name,
          }
        end
      end
    end
  end,
}



local muyexiaoliang_dianyingdaiyuan = General(extension, "muyexiaoliang_dianyingdaiyuan", "individual", 3, 3, General.Female)
muyexiaoliang_dianyingdaiyuan:addSkill(v_bingqi)
muyexiaoliang_dianyingdaiyuan:addSkill(v_lingku)

--------------------------------------------------
--棋圣
--TODO:魔法剑
--------------------------------------------------

local v_qisheng = fk.CreateActiveSkill{
  name = "v_qisheng",
  anim_type = "drawcard",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, player.HistoryPhase) == 0
  end,
  target_num = 0,
  min_card_num = 1,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:throwCard(effect.cards, self.name, player)
    if player:isAlive() then
      room:drawCards(player, #effect.cards, self.name)
      room:addPlayerMark(player, "@v_qisheng_card", #effect.cards)
      if player:getMark("@v_qisheng_card") >= 10 then
        room:notifySkillInvoked(player, self.name)
        player:broadcastSkillInvoke(self.name) --这个后续看效果 待定。
        --room:delay(2500)
        room:setPlayerMark(player, "@v_qisheng_card", 0)
        if not player:isKongcheng() then
          room:askForDiscard(player, 1, 1, false, self.name, false)
        end
        room:handleAddLoseSkills(player, "-v_qisheng|v_mogong_mfj|v_jiaojian_mfj", nil, true, false)
        --这里后续补获取魔法剑的方式
        for id = 0,500,1 do
          local card = Fk:getCardById(id)
          if card and card.name == VslUtil.Magic_Sword then
            room:obtainCard(player, card, true)
          end
        end
      end
    end
  end
}

--------------------------------------------------
--魔法剑·魔攻
--------------------------------------------------

local v_mogong_mfj = fk.CreateTriggerSkill{
  name = "v_mogong_mfj",
  anim_type = "offensive",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      data.card.trueName == "slash"
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    --确认是否发动技能。
    local prompt = "v_mogong_mfj_choice"
    if room:askForSkillInvoke(player, self.name, data, prompt) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local judge = {
      who = player,
      reason = self.name,
      pattern = ".|.|heart",
    }
    room:judge(judge)
    if judge.card.suit == Card.Heart then
      room:obtainCard(player, judge.card, true)
      data.disresponsive = true
    end
  end,
}

--------------------------------------------------
--魔法剑·交剑
--------------------------------------------------

local v_jiaojian_mfj = fk.CreateTriggerSkill{
  name = "v_jiaojian_mfj",
  events = {fk.AskForCardUse, fk.AskForCardResponse},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      (data.cardName == "jink" or (data.pattern and Exppattern:Parse(data.pattern):matchExp("jink|0|nosuit|none")))
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    --确认是否发动技能。
    local prompt = "v_jiaojian_mfj_choice"
    if room:askForSkillInvoke(player, self.name, data, prompt) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local judgeData = {
      who = player,
      reason = self.name,
      pattern = ".|.|spade",
    }
    room:judge(judgeData)

    if judgeData.card.suit == Card.Spade then
      room:obtainCard(player, judgeData.card, true)
      if event == fk.AskForCardUse then
        data.result = {
          from = player.id,
          card = Fk:cloneCard('jink'),
        }
        data.result.card.skillName = self.name

        if data.eventData then
          data.result.toCard = data.eventData.toCard
          data.result.responseToEvent = data.eventData.responseToEvent
        end
      else
        data.result = Fk:cloneCard('jink')
        data.result.skillName = self.name
      end

      return true
    end
  end
}

--------------------------------------------------
--水柳暮玥
--------------------------------------------------

local shuiliumuyue_benzhaimonv = General(extension, "shuiliumuyue_benzhaimonv", "individual", 4, 4, General.Agender)
shuiliumuyue_benzhaimonv:addSkill(v_qisheng)
shuiliumuyue_benzhaimonv:addRelatedSkill(v_mogong_mfj)
shuiliumuyue_benzhaimonv:addRelatedSkill(v_jiaojian_mfj)

--------------------------------------------------
--娴静
--------------------------------------------------

local v_xianjing = fk.CreateTriggerSkill{
  name = "v_xianjing",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  --触发条件：
  -- 遍历到的角色持有该技能；
  -- 触发时机的角色处于准备阶段;
  -- 触发时机的角色判定区中存在牌。
  -- （待补充）技能没有被无效；遍历到的角色的技能可以对触发时机的角色产生影响。
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and
      target.phase == Player.Start and
      #target:getCardIds(Player.Judge) > 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    --确认是否发动技能。
    local prompt = "v_xianjing_choice:"..target.id
    if room:askForSkillInvoke(player, self.name, data, prompt) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = {}
    if player.id ~= target.id then
      room:doIndicate( player.id, {target.id} )
    end
    target:turnOver()
    VslUtil.return_draw_pile(target, target:getCardIds(Player.Judge), self.name)
    room:delay(250)
  -- end
  end
}

--------------------------------------------------
--儒琴
--TODO：后续可以关注一下儒琴和奇遇的配合方式，后续处理；可能需要涉及所有伤害计算方式的修改。
-- 目前倾向于最多额外出牌阶段相比于原版可以多开一次儒琴
-- 但额外回合使用的儒琴应该不会影响到自己的正常回合。
--------------------------------------------------

local v_ruqin = fk.CreateTriggerSkill{
  name = "v_ruqin",
  --赋予进攻型技能定义
  anim_type = "offensive",
  --时机：阶段结束时
  events = {fk.EventPhaseEnd},
  --触发条件：
  --（阶段结束时）触发时机的角色为遍历到的角色；遍历到的角色具有本技能；
  --              被遍历到的角色处于出牌阶段。
  --              被遍历到的角色本回合未造成伤害，被遍历到的角色存在出牌阶段
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
    and player.phase == Player.Play
    and player:getMark("#turn_damage-turn") == 0 and VslUtil.exist_or_not(player, Player.Play) 
  end,
  on_cost = function(self, event, target, player, data)
    --确认是否发动技能。
    local room = player.room
    local targets = {}
    local others = room:getOtherPlayers(player, true, false)
    local prompt = "v_ruqin_ask"
    for _,p in ipairs(others) do
      local pm = p:getMark("#target_specified-turn")
      local mycr = false
      if pm ~= 0 then
        for _,t in ipairs(pm) do
          if t == player.id then
            mycr = true
            break
          end
        end
      end
      if mycr then
        --后续可以在这里补充以下判定：
        -- caneffect。
        if VslUtil.SkillCanTarget(p, player, self.name) then
          table.insert(targets, p.id)
        end
      end
    end
    if #targets > 0 then
      local ret = room:askForChoosePlayers(player, targets, 1, 1, prompt, self.name, true)
      --确认是否发动技能。
      if #ret > 0 then
        --后续可以在这里补充以下判定：
        -- 遍历到的角色本技能未被元初之类的无效，目标可以弃置遍历到的角色的牌。
        self.cost_data = ret[1]
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tar = room:getPlayerById(self.cost_data)
    tar:drawCards(1, self.name)
    room:damage{
      from = player,
      to = tar,
      damage = 1,
      skillName = self.name,
    }
  end,
}

--------------------------------------------------
--梦音茶糯
--------------------------------------------------

local mengyinchanuo_xiuwaihuizhong = General(extension, "mengyinchanuo_xiuwaihuizhong", "individual", 3, 3, General.Female)
mengyinchanuo_xiuwaihuizhong:addSkill(v_xianjing)
mengyinchanuo_xiuwaihuizhong:addSkill(v_ruqin)

--------------------------------------------------
--止鸽
--这个写法作为副将的时候刷新不了副将自己的限定技，麻了。
--------------------------------------------------

local v_zhige_gugu = fk.CreateActiveSkill{
  name = "v_zhige_gugu",
  anim_type = "support",
  card_num = 1,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < player.hp
  end,
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).trueName == "slash"
  end,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    -- room:addPlayerMark(player, "v_Not_clear_card_flag", 1)
    room:obtainCard(target, effect.cards[1], false, fk.ReasonGive)
    room:addPlayerMark(player, "@v_zhige_gugu-phase", 1)
    -- room:addPlayerMark(player, "v_Not_clear_card_flag", 0)
    room:addCardMark(Fk:getCardById(effect.cards[1]), "@@v_zhige_gugu-cm!l*", 1)
    local all_skills = Fk.generals[player.general]:getSkillNameList()
    if table.contains(all_skills, self.name) then
      for _, skill_name in ipairs(all_skills) do
        local skill = Fk.skills[skill_name]
        if player:usedSkillTimes(skill_name, Player.HistoryGame) > 0 
          and skill.frequency == Skill.Limited then
          player:setSkillUseHistory(skill_name, 0, Player.HistoryGame)
        end
      end
    end
    if player.deputyGeneral and player.deputyGeneral ~= "" then
      local all_skills_deputy = Fk.generals[player.deputyGeneral]:getSkillNameList()
      if table.contains(all_skills_deputy, self.name) then
        for _, skill_name in ipairs(all_skills_deputy) do
          local skill = Fk.skills[skill_name]
          if player:usedSkillTimes(skill_name, Player.HistoryGame) > 0 
            and skill.frequency == Skill.Limited then
            player:setSkillUseHistory(skill_name, 0, Player.HistoryGame)
          end
        end
      end
    end
  end,
}
local v_zhige_gugu_recover = fk.CreateTriggerSkill{
  name = "#v_zhige_gugu_recover",
  mute = true,
  anim_type = "recover",
  --时机：卡牌移动前，卡牌移动后
  events = {fk.BeforeCardsMove, fk.AfterCardsMove},
  --触发条件：
  -- 卡牌移动前：
  --  牌移动原因为弃置
  --  牌移动的目标为弃牌堆/处理区
  --  牌数大于0
  --  存在卡牌存在对应标记
  -- 卡牌移动后：
  --  牌移动原因为弃置
  --  牌移动的目标为弃牌堆/处理区
  --  牌数大于0
  --  存在卡牌存在对应标记
  can_trigger = function(self, event, target, player, data)
    if event == fk.BeforeCardsMove then
      for _, move in ipairs(data) do
        if move.moveReason == fk.ReasonDiscard 
          and (move.toArea == Card.DiscardPile or move.toArea == Card.Processing)
          -- and #move.ids > 0 
        then
          for _, info in ipairs(move.moveInfo) do
            local dis_card = Fk:getCardById(info.cardId)
            if dis_card and dis_card:getMark("@@v_zhige_gugu-cm!l*") > 0 then
              return true
            end
          end
        end
      end
    elseif event == fk.AfterCardsMove then
      for _, move in ipairs(data) do
        if move.moveReason == fk.ReasonDiscard 
          and (move.toArea == Card.DiscardPile or move.toArea == Card.Processing)
          -- and #move.ids > 0 
        then
          for _, info in ipairs(move.moveInfo) do
            local dis_card = Fk:getCardById(info.cardId)
            if dis_card and dis_card:getMark("v_zhige_gugu_trigger") > 0 then
              return true
            end
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    return true
  end,
  --使用流程：
  -- 卡牌移动后：
  --   为遍历到的角色提供特定标记
  on_use = function(self, event, target, player, data)
    --遍历全场所有存活角色，挑出其中未被横置的角色。
    local room = player.room
    if event == fk.BeforeCardsMove then
      for _, move in ipairs(data) do
        for _, info in ipairs(move.moveInfo) do
          local dis_card = Fk:getCardById(info.cardId)
          if dis_card and dis_card:getMark("@@v_zhige_gugu-cm!l*") > 0 then
            room:setCardMark(dis_card, "v_zhige_gugu_trigger", 1)
          end
        end
      end
    elseif event == fk.AfterCardsMove then
      local pla
      local dis_card
      for _, move in ipairs(data) do
        for _, info in ipairs(move.moveInfo) do
          dis_card = Fk:getCardById(info.cardId)
          if dis_card and dis_card:getMark("v_zhige_gugu_trigger") > 0 then
            room:setCardMark(dis_card, "v_zhige_gugu_trigger", 0)
            pla = room:getPlayerById(move.from)
            if pla and pla:isAlive() then
              room:sendLog{
                type = "#v_zhige_gugu_recover_log",
                from = pla.id,
                card = { dis_card.id },
                arg = "@@v_zhige_gugu-cm!l*",
              }
              room:recover({
                who = pla,
                num = 1,
                skillName = "v_zhige_gugu"
              })
            end
          end
        end
      end
    end
  end,
}

v_zhige_gugu:addRelatedSkill(v_zhige_gugu_recover)

--------------------------------------------------
--治疾
--------------------------------------------------

local v_zhiji = fk.CreateActiveSkill{
  name = "v_zhiji",
  anim_type = "control",
  frequency = Skill.Limited,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  target_num = 1,
  --card_num = 0,
  card_filter = function(self, to_select, selected, selected_targets)
    return false
  end,
  target_filter = function(self, to_select, selected, cards)
    local tar = Fk:currentRoom():getPlayerById(to_select)
    return VslUtil.SkillCanTarget(tar, Self, self.name) and #selected == 0
      and not tar:isAllNude()
  end,
  on_use = function(self, room, effect)
    --local players = room.players
    local from = room:getPlayerById(effect.from)
    local to = room:getPlayerById(effect.tos[1])
    -- local buddy = false
    -- if table.contains(from.buddy_list, to.id) then
    --   from:removeBuddy(to)
    --   buddy = true
    -- end
    local id = room:askForCardChosen(from, to, "hej", self.name)
    -- if buddy then
    --   from:addBuddy(to)
    -- end

    room:recastCard({id}, to, self.name)
  end,
}

--------------------------------------------------
--医怀
--------------------------------------------------

local v_yihuai = fk.CreateTriggerSkill{
  name = "v_yihuai",
  anim_type = "drawcard",
  events = {fk.HpRecover},
  frequency = Skill.Limited,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
      and data.card and not player:isNude()
  end,

  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "#v_yihuai_choice:::"..data.card.name
    local card = room:askForCard(player, 1, 1, true, self.name, true, ".", prompt)[1]
    if card then
      self.cost_data = card
      return true
    end
    -- if room:askForSkillInvoke(player, self.name, data, prompt) then
    --   return true
    -- end
  end,

  on_use = function(self, event, target, player, data)
    local room = player.room
    if room:getCardArea(data.card) == Card.Processing then
      room:throwCard({self.cost_data}, self.name, player, player)
      room:obtainCard(player.id, data.card, true, fk.ReasonPrey)
    end
  end,
}

--------------------------------------------------
--露蒂丝
--------------------------------------------------

local ludisi_guguyisheng = General(extension, "ludisi_guguyisheng", "individual", 3, 3, General.Female)
ludisi_guguyisheng:addSkill(v_zhige_gugu)
ludisi_guguyisheng:addSkill(v_zhiji)
ludisi_guguyisheng:addSkill(v_yihuai)

--------------------------------------------------
--紫禁
--------------------------------------------------

local v_zijin = fk.CreateTriggerSkill{
  name = "v_zijin",
  mute = true,
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  --触发条件：
  -- 触发时机的角色为遍历到的角色，遍历到的角色持有该技能；
  -- 触发时机的角色处于结束阶段;
  -- 触发时机的角色本回合未造成伤害；
  -- 触发时机的角色有牌。
  -- （待补充）技能没有被无效；遍历到的角色的技能可以对触发时机的角色产生影响。
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
      and player.phase == Player.Finish
      and player:getMark("#turn_damage-turn") == 0
      and (not player:isNude())
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = {}
    local others = room:getOtherPlayers(player, true, false)
    local prompt = "v_zijin_ask"
    for _,p in ipairs(others) do
      --后续可以在这里补充以下判定：
      -- caneffect，目标可以弃置遍历到的角色的牌(candiscard)。
      if VslUtil.SkillCanTarget(p, player, self.name) then
        table.insert(targets, p.id)
      end
    end
    if #targets > 0 then
      local ret = room:askForChoosePlayers(player, targets, 1, 1, prompt, self.name, true)
      --确认是否发动技能。
      if #ret > 0 then
        --后续可以在这里补充以下判定：
        -- 遍历到的角色本技能未被元初之类的无效，目标可以弃置遍历到的角色的牌。
        self.cost_data = ret[1]
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local targets = room:getPlayerById(self.cost_data)
    room:doAnimate("InvokeSkill", {
      name = self.name,
      player = player.id,
      skill_type = self.anim_type,
    })
    room:sendLog{
      type = "#v_skill_target",
      from = player.id,
      arg = self.name,
      to = { targets.id }
    }
    player:broadcastSkillInvoke(self.name)
    -- local buddy = false
    -- if table.contains(targets.buddy_list, player.id) then
    --   targets:removeBuddy(player)
    --   buddy = true
    -- end
    local throw_id = room:askForCardChosen(targets, player, "he", self.name)
    -- if buddy then
    --   targets:addBuddy(player)
    -- end

    room:throwCard(throw_id, self.name, player, targets)
    local car = Fk:getCardById(throw_id)
    if car.type == Card.TypeBasic then
      if not targets:isNude() then
        local card = room:askForCardChosen(player, targets, "he", self.name)
        room:obtainCard(player, card, false, fk.ReasonPrey)
      end
    else
      room:damage{
        from = player,
        to = targets,
        damage = 1,
        skillName = self.name,
      }
    end
  -- end
  end
}

--------------------------------------------------
--本怖
--------------------------------------------------

local v_benbu = fk.CreateTriggerSkill{
  name = "v_benbu",
  frequency = Skill.Wake,
  anim_type = "support",
  events = {fk.RoundStart},
  --触发条件：
  -- 遍历到的角色持有该技能；
  -- 遍历到的角色未使用过该技能
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  --觉醒条件：进行一次判定，结果点数<=游戏轮数则觉醒
  can_wake = function(self, event, target, player, data)
    local room = player.room
    local pattern = ".|1~" .. room:getTag("RoundCount")
    local judge = {
      who = player,
      reason = self.name,
      pattern = pattern,
    }
    room:judge(judge)
    local num = judge.card.number
    return num <= room:getTag("RoundCount")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    --后续这里可以补充动画和配音，以及角色图片&称号的变化。
    --回复一点体力并获得技能。
    room:recover({
      who = player,
      num = 1,
      recoverBy = player,
      skillName = self.name
    })
    room:handleAddLoseSkills(player, "v_chushou", nil)
  end,
}

--------------------------------------------------
--触手
--脱离濒危后重置技能次数还没写———
--------------------------------------------------

local v_chushou_re = fk.CreateTriggerSkill{
  name = "#v_chushou_re",
  events = {fk.AfterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes("v_chushou", Player.HistoryGame) > 0
      and not target.dead and not player.dead
  end,
  on_cost = function(self, event, target, player, data)
    return true
  end,
  on_use = function(self, event, target, player, data)
    -- local room = player.room
    player:setSkillUseHistory("v_chushou", 0, Player.HistoryGame)
  end,
}

local v_chushou = fk.CreateActiveSkill{
  name = "v_chushou",
  anim_type = "support",
  prompt = "#v_chushou_act",
  frequency = Skill.Limited,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  min_target_num = 1,
  --card_num = 0,
  card_filter = function(self, to_select, selected, selected_targets)
    return false
  end,
  --（待补充）canuse
  target_filter = function(self, to_select, selected)
    -- local target = Fk:currentRoom():getPlayerById(to_select)
    local target = Fk:currentRoom():getPlayerById(to_select)
    local player = Fk:currentRoom().current
    local pc = Self.player_cards[Player.Hand]
    --这玩意加载不出来,player直接显示nil，爆炸
    local pcl = #pc
    --可以在这里后续加caneffect
    return #selected < pcl and to_select ~= Self.id
      and VslUtil.SkillCanTarget(target, player, self.name)
    -- return #selected == 0
  end,
  on_use = function(self, room, effect)
    --local players = room.players
    local player = room:getPlayerById(effect.from)
    for _, pid in ipairs(effect.tos) do
      local target = room:getPlayerById(pid)
      room:doAnimate("InvokeSkill", {
        name = "v_zijin",
        player = player.id,
        skill_type = "offensive",
      })
      room:sendLog{
        type = "#v_skill_target",
        from = player.id,
        arg = "v_zijin",
        to = { target.id }
      }
      player:broadcastSkillInvoke("v_zijin")
      local buddy = false
      if table.contains(target.buddy_list, player.id) then
        target:removeBuddy(player)
        buddy = true
      end
      local throw_id = room:askForCardChosen(target, player, "he", self.name)
      if buddy then
        target:addBuddy(player)
      end
  
      room:throwCard(throw_id, self.name, player, target)
      local car = Fk:getCardById(throw_id)
      if car.type == Card.TypeBasic then
        if not target:isNude() then
          local card = room:askForCardChosen(player, target, "he", self.name)
          room:obtainCard(player, card, false, fk.ReasonPrey)
        end
      else
        room:damage{
          from = player,
          to = target,
          damage = 1,
          skillName = "v_zijin",
        }
      end
    end
  end,
}

v_chushou:addRelatedSkill(v_chushou_re)

--------------------------------------------------
--夏卜卜
--------------------------------------------------

local xiabubu_zhixingjiejie = General(extension, "xiabubu_zhixingjiejie", "individual", 4, 4, General.Agender)
xiabubu_zhixingjiejie:addSkill(v_zijin)
-- xiabubu_zhixingjiejie:addSkill(v_benbu)
xiabubu_zhixingjiejie:addSkill(v_chushou)

--------------------------------------------------
--神伴
--技能马克:后续可以补充光神的图片
--技能马克2：原Vup V1.0.1版本中技能指定顺序为ABCABC
--      但根据FK主创团队的说法，这里排序规则应该是AABBCC
--      如需维持原有规律，请参考“丰姿”
--------------------------------------------------

local v_shenban = fk.CreateActiveSkill{
  name = "v_shenban",
  anim_type = "support",
  prompt = "#v_shenban_act",
  can_use = function(self, player)
    return (not player:isNude())
  end,
  target_num = 1,
  card_num = 1,
  --可以弃置此牌，此牌颜色为红色。
  card_filter = function(self, to_select, selected, selected_targets)
    if #selected == 1 then return false end
    local card = Fk:getCardById(to_select)
    return card.color == Card.Red and (not Self:prohibitDiscard(card))
  end,
  --（待补充）canuse
  target_filter = function(self, to_select, selected)
    -- local target = Fk:currentRoom():getPlayerById(to_select)
    local target = Fk:currentRoom():getPlayerById(to_select)
    local player = Fk:currentRoom().current
    --可以在这里后续加caneffect
    return #selected == 0
      and VslUtil.SkillCanTarget(target, player, self.name)
    -- return #selected == 0
  end,
  --后续可以在这里补充元初类判定
  on_use = function(self, room, effect)
    --先拼点
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:throwCard(effect.cards, self.name, player)
    room:addPlayerMark(target, "@v_shenban", 1)
    if player.phase == Player.Play then
      player.room.logic:getCurrentEvent():findParent(GameEvent.Phase):shutdown()
    end
  end,
}
local v_shenban_tar = fk.CreateTriggerSkill{
  name = "#v_shenban_tar",
  --赋予输出型技能定义,
  anim_type = "offensive",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  mute = true,
  events = {fk.TargetSpecified},
  --触发条件：
  --             触发时机的角色为遍历到的角色，遍历到的角色存在神伴标记
  --             触发的牌真名为杀或为普通锦囊牌，触发的牌为实体牌
  --             本次流程中第一次触发这个时机（待定）
  can_trigger = function(self, event, target, player, data)
    return target == player and player:getMark("@v_shenban") > 0
    and (data.card.trueName == "slash" or (data.card.type == Card.TypeTrick and
    data.card.sub_type ~= Card.SubtypeDelayedTrick)) and data.card.id > 0
    and data.firstTarget
  end,
  --关于data.targetGroup和data.tos的区别后续可以用dbg处理
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:removePlayerMark(player, "@v_shenban", 1)
    local address = "./packages/"..VslUtil.extensionName.."/image/anim/v_shenban"
    room:setEmotion(player, address)
    local tarold = AimGroup:getAllTargets(data.tos)
    local tarnew = {}
    for _, p in ipairs(tarold) do
      TargetGroup:pushTargets(data.targetGroup, p)
      table.insert(tarnew, p)
      table.insert(tarnew, p)
    end
    --注释：发log用的to是一维数组，而tos是二维数组
    if not data.card:isVirtual() then
      room:sendLog{
        type = "#v_changetarget_log",
        from = player.id,
        to = tarnew,
        arg = self.name,
        card = { data.card.id },
      }
    elseif data.card:isVirtual() then
      room:sendLog{
        type = "#v_changetarget_virtual_log",
        from = player.id,
        to = tarnew,
        arg = self.name,
        arg2 = data.card:toLogString(),
      }
    end

  end,
}

--由于世界名画“五谷丰登和无懈可击”，这玩意还需要完善下再拿出去···
-- local v_shenban_tar = fk.CreateTriggerSkill{
--   name = "#v_shenban_tar",
--   --赋予输出型技能定义,
--   anim_type = "offensive",
--   --技能为锁定技，满足条件后强制发动
--   frequency = Skill.Compulsory,
--   events = {fk.AfterCardTargetDeclared},
--   --使用条件：
--   --             触发时机的角色为遍历到的角色，遍历到的角色存在神伴标记
--   --             触发的牌真名为杀或为普通锦囊牌，触发的牌为实体牌
--   can_trigger = function(self, event, target, player, data)
--     return target == player and player:getMark("@v_shenban") > 0
--     and (data.card.trueName == "slash" or (data.card.type == Card.TypeTrick and
--     data.card.sub_type ~= Card.SubtypeDelayedTrick)) and data.card.id > 0
--   end,
--   -- on_cost = function(self, event, target, player, data)
--   --   local type = data.card:getTypeString()
--   --   return #player.room:askForDiscard(player, 1, 1, false, self.name, true, ".|.|.|.|.|"..type,
--   --     "#fengzi-invoke:::"..type..":"..data.card:toLogString()) > 0
--   -- end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     room:removePlayerMark(player, "@v_shenban", 1)
--     room:setPlayerMark(player, self.name, TargetGroup:getRealTargets(data.tos))
--   end,

--   refresh_events = {fk.CardUseFinished},
--   can_refresh = function(self, event, target, player, data)
--     return target == player and player:hasSkill(self.name, true) and player:getMark(self.name) ~= 0
--   end,
--   on_refresh = function(self, event, target, player, data)
--     local room = player.room
--     room:setEmotion(player, "./packages/vupslash/image/anim/v_shenban")
--     local targets = player:getMark(self.name)
--     room:setPlayerMark(player, self.name, 0)
--     for _, id in ipairs(targets) do
--       if room:getPlayerById(id).dead then
--         table.removeOne(targets, id)
--       end
--     end
--     if #targets > 0 then
--       --注释：发log用的to是一维数组，而tos是二维数组
--       room:sendLog{
--         type = "#v_shenban_log",
--         from = player.id,
--         -- to = targets,
--         arg = self.name,
--         card = { data.card.id },
--       }
--       --这牌要不要把原牌带的技能带上后续再说。
--       room:useVirtualCard(data.card.name, nil, player, table.map(targets, function(id) return room:getPlayerById(id) end), self.name, true)
--     end
--   end,
-- }

v_shenban:addRelatedSkill(v_shenban_tar)

--------------------------------------------------
--逝随
--------------------------------------------------

local v_shisui = fk.CreateTriggerSkill{
  name = "v_shisui",
  anim_type = "support",
  events = {fk.EnterDying},
  --使用条件：
  --  遍历到的角色具有本技能
  --  触发时机的角色存在且不为遍历到的角色，触发时机的角色体力小于1
  --  （待补充）not skillnullify，player:caneffect
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) 
    and target and target ~= player and target.hp <1 
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local choice = room:askForSkillInvoke(player, self.name, data)
    return choice
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if target ~= player then
      --doindicate的两个参数一个为integer，一个为table
      room:doIndicate(player.id, { target.id })
    end
    --降低一点体力上限，回复对方一点体力。
    room:changeMaxHp(player, -1)
    room:recover{
      who = target,
      num = 1,
      recoverBy = player,
      skillName = self.name,
    }
    -- room:setPlayerMark(target, "v_shisui_alive", 1)
    -- data.extra_data.shisui = target.id
    -- 如果以下条件存在，触发后续机制：
    --  触发时机的角色存在且存活，触发时机的角色存在牌
    if target and target:isAlive() and not target:isAllNude()
      and player and player:isAlive()
    then
      local ids = {}
      local ids_loc = {}
      local take_ids = {}
      -- local show_ids = {}
      -- local can_choose_ids = {}
      local cannot_choose_ids = {}
      local hand = target:getCardIds(Player.Hand)
      local equip = target:getCardIds(Player.Equip)
      local judge = target:getCardIds(Player.Judge)
      for _,cd in ipairs(hand) do
        table.insert(ids, cd)
        table.insert(ids_loc, {cd, hand})
      end
      for _,cd in ipairs(equip) do
        table.insert(ids, cd)
        table.insert(ids_loc, {cd, equip})
      end
      for _,cd in ipairs(judge) do
        table.insert(ids, cd)
        table.insert(ids_loc, {cd, judge})
      end
      --进入拿牌环节
      while #ids ~= #cannot_choose_ids do
        -- room:fillAG(player, show_ids, cannot_choose_ids)
        room:fillAG(player, ids)
        for _,p in ipairs(cannot_choose_ids) do
          room:takeAG(target, p, room.players)
          -- table.removeOne(ids, p)
        end
        local id1 = room:askForAG(player, ids, false, self.name)
        -- local id1 = room:askForAG(player, can_choose_ids, true, self.name)
        if id1 and id1 ~= -1 then
          room:closeAG(player)
          -- dummy:addSubcard(id1)
          local card1 = Fk:getCardById(id1)
          table.insert(take_ids, id1)
          for _,cd in ipairs(ids_loc) do
            local car = Fk:getCardById(cd[1])
            if car == card1 then
              for _,cd in ipairs(cd[2]) do
                table.insert(cannot_choose_ids, cd)
              end
            end
          end
        end
      end
      if #take_ids > 0 then
        room:moveCards({
          ids = take_ids,
          from = target.id,
          to = player.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonPrey,
        })
        -- room.obtainCard(player, dummy, false, fk.ReasonPrey)  --等会用movecard试试
      end
    end
    -- elseif event == fk.AfterDying then
    --   return true
    -- end
  end,
}

-- 本版本暂时废弃
-- local v_shisui = fk.CreateTriggerSkill{
--   name = "v_shisui",
--   anim_type = "support",
--   events = {fk.EnterDying, fk.AfterDying},
--   --使用条件：
--   -- 进入濒危状态:
--   --  遍历到的角色具有本技能
--   --  触发时机的角色存在且不为遍历到的角色，触发时机的角色体力小于1
--   --  （待补充）not skillnullify，player:caneffect
--   -- 脱离濒危状态:
--   --  遍历到的角色具有本技能（为了防止插结失去技能，可以删掉）
--   -- 触发时机的角色存在且存活，触发时机的角色存在牌，触发时机的角色存在标记（待定）
--   -- 注释：这个标记需要在玩家死亡后可以自动被清理掉的能力，先按照会被清洗掉交给触发时机的角色。
--   can_trigger = function(self, event, target, player, data)
--     if event == fk.EnterDying then
--       return player:hasSkill(self) 
--       and target and target ~= player and target.hp <1 
--     elseif event == fk.AfterDying then
--       return player:hasSkill(self) 
--         and target and target:isAlive() and not target:isAllNude() 
--         and data.extra_data.shisui == target.id
--     end
--   end,
--   on_cost = function(self, event, target, player, data)
--     if event == fk.EnterDying then
--       local room = player.room
--       local choice = room:askForSkillInvoke(player, self.name, data)
--       return choice
--     elseif event == fk.AfterDying then
--       return true
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     if event == fk.EnterDying then
--       if target ~= player then
--         --doindicate的两个参数一个为integer，一个为table
--         room:doIndicate(player.id, { target.id })
--       end
--       --降低一点体力上限，回复对方一点体力。
--       room:changeMaxHp(player, -1)
--       room:recover{
--         who = target,
--         num = 1,
--         recoverBy = player,
--         skillName = self.name,
--       }
--       -- room:setPlayerMark(target, "v_shisui_alive", 1)
--       data.extra_data.shisui = target.id
--     elseif event == fk.AfterDying then
--       return true
--     end
--   end,
-- }

--------------------------------------------------
--绫濑光
--------------------------------------------------

local linglaiguang_shengsixiangyi = General(extension, "linglaiguang_shengsixiangyi", "individual", 4, 4, General.Agender)
linglaiguang_shengsixiangyi:addSkill(v_shenban)
linglaiguang_shengsixiangyi:addSkill(v_shisui)
-- linglaiguang_shengsixiangyi:addSkill(v_lose)
-- linglaiguang_shengsixiangyi:addSkill(v_cheat)

--------------------------------------------------
--血林
--------------------------------------------------

local v_xuelin = fk.CreateTriggerSkill{
  name = "v_xuelin",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) 
    and data.from and not data.from.dead
      and data.damage > 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local from = data.from
    if from and player ~= from then room:doIndicate(player.id, {from.id}) end
    local judge = {
      who = from,
      reason = self.name,
      pattern = ".",
    }
    room:judge(judge)
    if judge.card.color == Card.Red then
      room:damage{
        from = player,
        to = from,
        damage = 1,
        skillName = self.name,
      }
    elseif judge.card.color == Card.Black then
      room:askForDiscard(from, 2, 2, true, self.name, false)
    end
  end,
}

--------------------------------------------------
--寻腥
--------------------------------------------------

local v_xunxing = fk.CreateTriggerSkill{
  name = "v_xunxing",
  anim_type = "defensive",
  events = {fk.DamageInflicted},
  --使用条件：（已完成）
  -- 伤害>0，存在源与目标；
  -- 遍历到的角色在源的攻击范围内，目标为触发时机的角色，触发时机的角色不为遍历到的角色；
  -- 遍历到的角色区域内有牌，遍历到的角色具有本技能。
  can_trigger = function(self, event, target, player, data)
    return data.damage > 0 
    --  and data.from and data.to
     and data.from and data.from:inMyAttackRange(player) and (data.to or {}) == target and target ~= player
     and not player:isNude() and player:hasSkill(self)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "v_xunxing_ask:"..target.id
    local card = room:askForCard(player, 1, 1, true, self.name, true, ".", prompt)[1]
    if card then
      self.cost_data = card
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local card = Fk:getCardById(self.cost_data)
    room:moveCardTo(card, Card.DrawPile, nil, fk.ReasonPut, self.name, nil, false)
    room:damage{
      from = data.from,
      to = player,
      damage = data.damage,
      damageType = data.damageType,
      skillName = self.name,
      card = data.card,
    }
    return true
  end,
}

--------------------------------------------------
--奈奈莉娅
--------------------------------------------------

local nainailiya_yuanbenlinyuan = General(extension, "nainailiya_yuanbenlinyuan", "individual", 4, 4, General.Female)
nainailiya_yuanbenlinyuan:addSkill(v_xuelin)
nainailiya_yuanbenlinyuan:addSkill(v_xunxing)

--------------------------------------------------
--炽翎
--TODO:如果在展示牌之后出现因为其他技能导致的弃置需要思考方案
--------------------------------------------------

local v_chiling = fk.CreateViewAsSkill{
  name = "v_chiling",
  anim_type = "offensive",
  prompt = "#v_chiling_act",
  pattern = "fire_attack",
  card_filter = function(self, to_select, selected)
    local card = Fk:getCardById(to_select)
    return #selected == 0 and card.color == Card.Red
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    local c = Fk:cloneCard("fire_attack")
    c.skillName = self.name
    c:addSubcard(cards[1])
    return c
  end,
  enabled_at_play = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
}
local v_chiling_next = fk.CreateTriggerSkill{
  name = "#v_chiling_next",
  anim_type = "offensive",
  mute = true,
  --时机：卡牌使用宣告后，卡牌移动后，伤害造成时
  events = {fk.AfterCardUseDeclared, fk.AfterCardsMove, fk.DamageCaused},
  --使用条件：
  -- 卡牌使用宣告后：触发时机的角色为遍历到的角色，遍历到的角色存在此技能
  --                遍历到的角色存在手牌，牌名为火攻，
  --                牌的技能名为v_chiling；
  -- 卡牌移动后：遍历到的角色存在此技能
  --            存在特定mark，弃牌skillname为火攻，弃牌原因为弃置【如果不对，后续用dbg查】；
  -- 伤害造成时：触发时机的角色为遍历到的角色，遍历到的角色存在此技能
  --             伤害>0，造成伤害的牌为火攻，
  --             造成伤害的牌的技能名为v_chiling，存在特定mark。
  can_trigger = function(self, event, target, player, data)
    if event == fk.AfterCardUseDeclared then
      return target == player and player:hasSkill(self) 
        and (not player:isKongcheng()) and data.card and data.card.name == "fire_attack"
        and data.card.skillName == "v_chiling"
        -- and table.contains(data.card.skillNames, "v_chiling")
    elseif event == fk.AfterCardsMove then
      local room = player.room
      local move = data
      --后续discardpile可能删掉
      if player:hasSkill(self) and (not (player:getMark("v_chiling_id") > 0) and move.skillName == "fire_attack"
      and move.from == player.id 
      and move.toArea == Card.DiscardPile
      ) then
        return false
      end
      for _, move in ipairs(data) do
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand 
            and (room:getCardArea(info.cardId) == Card.DiscardPile or room:getCardArea(info.cardId) == Card.Processing)
            and info.cardId == player:getMark("v_chiling_id") then
            return true
          end
        end
      end
    elseif event == fk.DamageCaused then
      return target == player and player:hasSkill(self) 
        and data.damage > 0 and data.card and data.card.name == "fire_attack" 
        and data.card and data.card.skillName == "v_chiling" and player:getMark("v_chiling_damage") > 0
        -- and data.card and table.contains(data.card.skillNames, "v_chiling") and player:getMark("v_chiling_damage") > 0
      end
  end,
  --使用条件：
  -- 卡牌使用宣告后：需要askforcard（仅限手牌），存在且非虚拟牌则return true；
  -- 其他：return true
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.AfterCardUseDeclared then
      local prompt = "v_chiling_card"
      local card = room:askForCard(player, 1, 1, false, self.name, true, ".", prompt)[1]
      if card and card > 0 then
        self.cost_data = card
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.AfterCardUseDeclared then
      room:sendLog{
        type = "#v_chiling_selected_log",
        from = player.id,
        arg = self.name,
        arg2 = 1,
      }
      local cid = self.cost_data
      room:setPlayerMark(player, "v_chiling_id", cid)
      local hand = player:getCardIds(Player.Hand)
      local hands = {}
      for _,p in ipairs(hand) do
        if p ~= cid then
          table.insert(hands, p)
        end
      end
      if #hands > 0 then
        player:showCards(hands)
        room:delay(500)
      end
    elseif event == fk.AfterCardsMove then
      room:setPlayerMark(player, "v_chiling_id", 0)
      room:setPlayerMark(player, "v_chiling_damage", 1)
    elseif event == fk.DamageCaused then
      local address = "./packages/"..VslUtil.extensionName.."/image/anim/v_chiling_two"
      room:setEmotion(player, address)
      data.damage = data.damage + 1
      room:setPlayerMark(player, "v_chiling_id", 0)
      room:setPlayerMark(player, "v_chiling_damage", 0)
    end
  end,

  refresh_events = {fk.CardUseFinished},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
      and (player:getMark("v_chiling_id") > 0 or player:getMark("v_chiling_damage") > 0)
      and data.card
      and data.card.name == "fire_attack"
      and data.card.skillName == "v_chiling"
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "v_chiling_id", 0)
    room:setPlayerMark(player, "v_chiling_damage", 0)
  end,
}
v_chiling:addRelatedSkill(v_chiling_next)

--------------------------------------------------
--离息
--------------------------------------------------

local v_lixi = fk.CreateTriggerSkill{
  name = "v_lixi",
  anim_type = "support",
  -- mute = true,
  -- 这是最接近离场的时机···
  events = {fk.AskForPeachesDone},
  can_trigger = function(self, event, target, player, data)
    if not (target == player and player:hasSkill(self)) then return false end
    local room = player.room
    local draw = room.draw_pile
    for _,p in ipairs(draw) do
    local card = Fk:getCardById(p)
      -- print(card.name)
      if card.name == "fan" then
        return true
      end
    end
  end,
  on_cost = function() return true end,
  on_use = function(self, event, target, player, data)
    return true
  end,
}

--------------------------------------------------
--角色特性：翼之涅槃
--耦合进aux_skill中
--------------------------------------------------

local v_characteristic_niepan = fk.CreateTriggerSkill{
  name = "#v_characteristic_niepan",
  anim_type = "special",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  -- events = {fk.GameStart, fk.Deathed},
  events = {fk.GameStart},
  can_trigger = function(self, event, target, player, data)
    if event == fk.GameStart then
      return player:hasSkill(self)
    -- elseif event == fk.Deathed then
    --   return target == player and player:hasSkill(self.name, true, true)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    -- if event == fk.GameStart then
    --   for _, p in ipairs(room:getAllPlayers()) do
    --     --这里后续可以加入特殊疲劳机制判定（例如秋凛子）
    --     if p:getMark("v_phoenix") == 0 
    --       and p:getMark("v_noexhaustion") == 0 
    --     then
    --       room:setPlayerMark(p, "v_phoenix", 1)
    --     end
    --   end
    -- elseif event == fk.Deathed then
    --   for _, p in ipairs(room:getAllPlayers()) do
    --     --这里后续可以加入特殊疲劳机制判定（例如秋凛子）
    --     if p:getMark("v_phoenix") > 0 then
    --       room:setPlayerMark(p, "v_phoenix", 0)
    --     end
    --   end
    -- end
  end,
}

--------------------------------------------------
--秋乌
--------------------------------------------------

local qiuwu_chiwuliuhuo = General(extension, "qiuwu_chiwuliuhuo", "individual", 3, 3, General.Bigender)
qiuwu_chiwuliuhuo:addSkill(v_chiling)
qiuwu_chiwuliuhuo:addSkill(v_lixi)
-- qiuwu_chiwuliuhuo:addSkill(v_characteristic_niepan)

--------------------------------------------------
--渴欲
--------------------------------------------------

local v_keyu = fk.CreateTriggerSkill{
  name = "v_keyu",
  --赋予防御型技能定义
  anim_type = "defensive",
  --时机：体力回复后
  events = {fk.HpRecover},
  --使用条件：
  --遍历到的角色具有本技能、触发时机的角色不为遍历到的角色；
  --...
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target ~= player
    and not target:isNude() and data.num > 0
    and player:usedSkillTimes(self.name, Player.HistoryRound) < 1
  end,
  -- 反正是默认的，先这么放着
  -- on_cost = function(self, event, target, player, data)
  --   return true
  -- end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if target ~= player then
      --doindicate的两个参数一个为integer，一个为table
      room:doIndicate(player.id, { target.id })
    end
    room:setPlayerMark(player, "@@v_keyu_used-round", 1)
    if not target:isNude() then
      -- local buddy = false
      -- if table.contains(player.buddy_list, target.id) then
      --   player:removeBuddy(target)
      --   buddy = true
      -- end
      local id = room:askForCardChosen(player, target, "he", self.name)
      -- if buddy then
      --   player:addBuddy(target)
      -- end
      local card = Fk:getCardById(id)
      target:showCards(card)
      room:moveCardTo(card, Player.Hand, player, fk.ReasonPrey, self.name, nil, true)
      if card and card.trueName == "slash" then
        room:loseHp(target, 1, self.name)
      end
    end
  end,
}

--------------------------------------------------
--纤柔
--FIXME:流失体力不触发
--------------------------------------------------

local v_xianrou_prohibit = fk.CreateProhibitSkill{
  name = "#v_xianrou_prohibit",
  --闪电这个版本还是能挂你脑门上的。
  is_prohibited = function(self, from, to, card)
    if to:hasSkill("v_xianrou") and from ~= to and card.suit == Card.Spade then
      return true
    end
  end,
}
local v_xianrou = fk.CreateTriggerSkill{
  name = "v_xianrou",
  --赋予防御型技能定义
  anim_type = "defensive",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  --时机：阶段变化时
  events = {fk.Damaged},
  --使用条件：
  --触发时机的角色为遍历到的角色、遍历到的角色具有本技能；
  --受到的伤害大于0，造成伤害的角色存在且存活，造成伤害的角色不为遍历到的角色。
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) 
    and data.damage > 0 and data.from and data.from:isAlive()
    and data.from ~= player
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tar = data.from
    local prompt = "#v_xianrou_choice:"..player.id
    --doindicate的两个参数一个为integer，一个为table
    room:doIndicate(player.id, { tar.id })
    -- 这里原版存在一个caneffect询问
    local card = room:askForCard(tar, 1, 1, true, self.name, true, ".|.|spade", prompt)[1]
    if card then
      --交牌
      room:moveCardTo(card, Player.Hand, player, fk.ReasonGive, self.name, nil, true)
    else
      room:loseHp(tar, 1, self.name)
    end
  end,
}

v_xianrou:addRelatedSkill(v_xianrou_prohibit)

--------------------------------------------------
--芳乃推
--------------------------------------------------

local fangnaitui_yinyangmeiying = General(extension, "fangnaitui_yinyangmeiying", "individual", 3, 3, General.Bigender)
fangnaitui_yinyangmeiying:addSkill(v_keyu)
fangnaitui_yinyangmeiying:addSkill(v_xianrou)

--------------------------------------------------
--宵暗
--------------------------------------------------

local v_xiaoan = fk.CreateTriggerSkill{
  name = "v_xiaoan",
  anim_type = "defensive",
  events = {fk.CardEffectCancelledOut},
  --使用条件：
  --存在目标，目标为遍历到的角色，目标在场，目标具有本技能；
  --存在使用的牌。
  --(现在的写法可能导致)
  can_trigger = function(self, event, target, player, data)
    return data.to and player.id == data.to and player:isAlive() and player:hasSkill(self)
      and data.card
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    --后续这里可以加技能无法指定谁之类的判定在这里。
    -- local targets = table.map(room:getOtherPlayers(player), function(p) return p.id end)
    local fir_targets = table.map(room:getOtherPlayers(player), function(p) return p.id end)
    local targets = {}
    --这里后续可以加caneffect
    for _, pid in ipairs(fir_targets) do
      if VslUtil.SkillCanTarget(room:getPlayerById(pid), player, self.name) then
        table.insert(targets, pid)
      end
    end
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#v_xiaoan_choice", self.name, true)
    --后续这里可以加技能失效的判定在这里。
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tar = room:getPlayerById(self.cost_data)
    local judge = {
      who = tar,
      reason = self.name,
      pattern = ".|.|spade,club,diamond",
    }
    room:judge(judge)
    local result = judge.card
    if result.suit == Card.Spade then
      room:damage{
        from = player,
        to = tar,
        damage = 1,
        damageType = fk.ThunderDamage,
        skillName = self.name,
      }
    elseif result.suit == Card.Club then
      room:damage{
        from = player,
        to = tar,
        damage = 1,
        damageType = fk.IceDamage,
        skillName = self.name,
      }
    elseif result.suit == Card.Diamond then
      room:damage{
        from = player,
        to = tar,
        damage = 1,
        damageType = fk.FireDamage,
        skillName = self.name,
      }
    -- elseif result.suit == Card.Heart then
    --   room:damage{
    --     from = player,
    --     to = tar,
    --     damage = 1,
    --     damageType = fk.ThunderDamage,
    --     skillName = self.name,
    --   }
    --   room:damage{
    --     from = player,
    --     to = tar,
    --     damage = 1,
    --     damageType = fk.IceDamage,
    --     skillName = self.name,
    --   }
    --   room:damage{
    --     from = player,
    --     to = tar,
    --     damage = 1,
    --     damageType = fk.FireDamage,
    --     skillName = self.name,
    --   }
    end
  end,
}

--------------------------------------------------
--绝断
--------------------------------------------------

local v_jueduan = fk.CreateTriggerSkill{
  --（刚需）技能认证名
  name = "v_jueduan",
  --(非必要）赋予进攻型技能定义
  anim_type = "offensive",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  --时机：受到伤害时，造成伤害时
  events = {fk.DamageCaused},
  --触发条件：
  --触发时机的角色为遍历到的角色、遍历到的角色具有本技能、造成的伤害大于0；
  --非普通伤害
  --受到伤害的角色存在且存活（未完成）
  --遍历到的角色装备区牌数小于受到伤害的角色装备区牌数（未完成）
  --(后续补充)非光伤
  can_trigger = function(self, event, target, player, data)
    if not (target == player and player:hasSkill(self) and
      data.damage > 0 and data.damageType ~= fk.NormalDamage and
      data.to and data.to:isAlive() and
      #player:getCardIds(Player.Equip) < #data.to:getCardIds(Player.Equip)) then 
      return false
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage + 1
  end,
}

--------------------------------------------------
--能美枫铃
--------------------------------------------------

local nengmeifengling_lanmeiyushi = General(extension, "nengmeifengling_lanmeiyushi", "individual", 3, 3, General.Bigender)
nengmeifengling_lanmeiyushi:addSkill(v_xiaoan)
nengmeifengling_lanmeiyushi:addSkill(v_jueduan)

--------------------------------------------------
--芸芸
--------------------------------------------------

local v_yunyun = fk.CreateTriggerSkill{
  name = "v_yunyun",
  --赋予摸牌型技能定义
  anim_type = "drawcard",
  -- --时机：手牌结算后
  -- events = {fk.CardUseFinished},
  --时机：宣告手牌使用时
  events = {fk.AfterCardUseDeclared, fk.CardResponding},
  --触发条件：
  --触发时机的角色为遍历到的角色、遍历到的角色具有本技能
  --本回合此技能触发次数<1
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
      and player:usedSkillTimes(self.name, Player.HistoryTurn) < 1
      and (not player:isNude())
  end,
  --使用条件：
  -- 卡牌使用宣告后：需要askforcard，存在且非虚拟牌则return true；
  -- 其他：return true
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local prompt = "#v_yunyun_choice"
    local card = room:askForCard(player, 1, 1, true, self.name, true, ".", prompt)[1]
    if card and card > 0 then
      self.cost_data = card
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local car = self.cost_data
    room:recastCard(car, player, self.name)
  end,
}

--------------------------------------------------
--欣荣
--------------------------------------------------

local v_xinrong = fk.CreateTriggerSkill{
  name = "v_xinrong",
  --赋予摸牌型技能定义
  anim_type = "drawcard",
  --时机：阶段开始时
  events = {fk.EventPhaseStart},
  --触发条件：
  --触发时机的角色为遍历到的角色；
  --遍历到的角色处于结束阶段：遍历到的角色在场且具有本技能（具有本技能就够了，hasskill自己会判断的），遍历到的角色getlosthp>0
  --遍历到的角色处于准备阶段：遍历到的角色欣荣mark大于0
  can_trigger = function(self, event, target, player, data)
    --阶段变化时，实现“是否跳出牌”的效果。
    --exist_or_not：用来确认是否跳过对应阶段，类似于以前的Player:isSkipped()
    if target == player then
      if player.phase == Player.Finish then
        return player:hasSkill(self) and player:getLostHp() > 0
      elseif player.phase == Player.Start then
        return player:getMark("v_xinrong_used") > 0
      end
    end
  end,
  --使用条件：
  --遍历到的角色处于结束阶段：askforskillinvoke
  --遍历到的角色处于准备阶段：return true
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if (player.phase == Player.Finish and room:askForSkillInvoke(player, self.name, data)) 
      or player.phase == Player.Start then
      return true
    end
  end,
  --使用效果：
  --遍历到的角色处于结束阶段：设立X，作为标记，恢复等量体力，摸等量张牌，摸牌时候为每一张牌提供cardmark
  --遍历到的角色处于准备阶段：清理标记，失去体力，跑一遍手里的牌，如果有cardmark就弃置
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player.phase == Player.Finish then
      room:setPlayerMark(player, "v_xinrong_used", 1)
      local X = math.min(player:getLostHp(), #room:getAlivePlayers())
      if X > 0 then
        room:recover{
          who = player,
          num = X,
          recoverBy = player,
          skillName = self.name,
        }
        room:setPlayerMark(player, "@v_xinrong", X)
      end
      local cards = player:drawCards(X, self.name)
      player:showCards(cards)
      for _,id in ipairs(cards) do
        room:setPlayerMark(player, "v_xinrong_card_"..id, 1)
        room:setCardMark(Fk:getCardById(id), "@@v_xinrong-cm!dc*", 1)
      end
    elseif player.phase == Player.Start then
      local allcards = {}
      local throw_cards = {}
      room:setPlayerMark(player, "v_xinrong_used", 0)
      if player:getMark("@v_xinrong") > 0 then
        room:loseHp(player, player:getMark("@v_xinrong"), self.name)
        room:setPlayerMark(player, "@v_xinrong", 0)
      end
      for _,mark in ipairs(player:getMarkNames()) do
        if string.sub(mark, 1, 15) == "v_xinrong_card_" and player:getMark(mark) > 0 then
          local id = tonumber(string.sub(mark, 16, -1))
          table.insertTable(allcards, target:getCardIds(Player.Hand))
          table.insertTable(allcards, target:getCardIds(Player.Equip))
          for _,cid in ipairs(allcards) do
            if cid == id then
              table.insertIfNeed(throw_cards, cid)
            end
          end
          room:setPlayerMark(player, mark, 0)
        end
      end
      if #throw_cards > 0 then
        room:throwCard(throw_cards, self.name, player, player)
      end
    end
  end,
}

--------------------------------------------------
--哈娜
--------------------------------------------------

local hana_menglufanhua = General(extension, "hana_menglufanhua", "individual", 4, 4, General.Female)
hana_menglufanhua:addSkill(v_yunyun)
hana_menglufanhua:addSkill(v_xinrong)
-- hana_menglufanhua:addSkill(v_cheat)

--------------------------------------------------
--冰沙
--------------------------------------------------

local v_bingsha = fk.CreateTriggerSkill{
  name = "v_bingsha",
  --赋予支援型技能定义
  anim_type = "support",
  --时机：阶段变化时，宣告手牌使用时
  events = {fk.EventPhaseChanging, fk.AfterCardUseDeclared},
  --触发条件（已完成）：
  --遍历到的角色存在此技能。
  --  阶段变化时：
  --    触发时机的角色为遍历到的角色；（已完成）
  --    将进入出牌阶段；（已完成）
  --    未跳过出牌阶段；（已完成）
  --  宣告手牌使用时：（已完成）
  --    触发时机的角色不为遍历到的角色
  --    存在牌；牌的名字为“冰杀”
  --    一种我暂时不确定情况但是在曹操的奸雄里用到的机制: 牌在处理区时【弃牌区是否需要另议】，牌为虚拟/实体牌
  can_trigger = function(self, event, target, player, data)
    local room = player.room
    if not player:hasSkill(self) then return false end
    if event == fk.EventPhaseChanging then
      return target == player
      and data.to == Player.Draw and VslUtil.exist_or_not(player, Player.Draw)
    elseif event == fk.AfterCardUseDeclared then
      return target ~= player and data.card 
      -- and data.card.trueName == "slash" 
      and data.card.name == "v_ice__slash" and
      table.every(data.card:isVirtual() and data.card.subcards or {data.card.id}, function(id) return room:getCardArea(id) == Card.Processing end)
    end
  end,
  --使用条件（已完成）：
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseChanging then
      if room:askForSkillInvoke(player, self.name, data, "#v_bingsha_choice") then
        return true
      end
    --满足技能发动要求后，锁定发动。
    elseif event == fk.AfterCardUseDeclared then
      return true
    end
  end,
  --使用效果（未完成）：
  --阶段变化时：
  --  检索牌堆中的桃，获得其中随机一张。（已完成）
  --宣告手牌使用时：
  --  获得之。
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseChanging then
      --获取牌堆中的"桃"。
      local allcards = {}
      table.insertTable(allcards, room.draw_pile)
      local peaches = table.filter(allcards, function(id)
        local card = Fk:getCardById(id)
        return card.name == "peach"
      end)
      if #peaches > 0 then
        local x = #peaches
        local c = math.random(1, x)
        local cid = peaches[c]
        --这种函数可以从表中随机选n个元素并返回一张表，如果n是nil，那么返回的就不是表而是单个元素
        --local card = table.random(peaches, nil)
        local address = "./packages/"..VslUtil.extensionName.."/image/skill/lixingyu"..math.random(1,2)
        room:setEmotion(player, address)
        room:obtainCard(player, cid, true, fk.ReasonPrey)
      else
        room:sendLog{
          type = "#v_skill_find_fail",
          arg = self.name,
          arg2 = "peach",
        }
      end
      return true
    --满足技能发动要求后，锁定发动。
    elseif event == fk.AfterCardUseDeclared then
      local address = "./packages/"..VslUtil.extensionName.."/image/skill/lixingyu"..math.random(5,6)
      room:setEmotion(player, address)
      room:obtainCard(player.id, data.card, true, fk.ReasonPrey)
    end
  end,
}

--------------------------------------------------
--冰身
--------------------------------------------------

local v_bingshen = fk.CreateTriggerSkill{
  name = "v_bingshen",
  --赋予防御型技能定义
  anim_type = "defensive",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  --时机：指定目标时，受到伤害时
  events = {fk.TargetSpecified, fk.DamageInflicted},
  --触发条件（已完成）：
  --遍历到的角色存在此技能。
  --  指定目标时：
  --    遍历到的角色未装备防具；存在牌，且牌的truename为“杀”；
  --    卡的颜色为黑色
  --    牌的目标存在，牌的目标中存在遍历到的角色
  --    本次流程中第一次触发这个时机（待定）
  --  受到伤害时：
  --    触发时机的角色为遍历到的角色；受到的伤害大于0，受到的伤害为火焰伤害
  can_trigger = function(self, event, target, player, data)
    -- local room = player.room
    -- local pla = room:getPlayerById(data.from)
    if not player:hasSkill(self) then return false end
    if event == fk.TargetSpecified then
      local target_contain_player = false
      for _, p in ipairs(AimGroup:getAllTargets(data.tos)) do
        if p == player.id then
          target_contain_player = true
        end
      end
      return not player:getEquipment(Card.SubtypeArmor)
      and data.card and data.card.trueName == "slash" 
      and data.card.color == Card.Black
      -- and pla and pla:isAlive() and pla ~= player
      and #AimGroup:getAllTargets(data.tos) > 0 and target_contain_player
      and data.firstTarget
    elseif event == fk.DamageInflicted then
      return target == player 
      and data.damage > 0 and data.damageType == fk.FireDamage
    end
  end,
  --使用效果（已完成）：
  --  指定目标时：
  --    如果非冰杀，播放表情（已完成）
  --    令杀无效化（已完成）
  --  受到伤害时：
  --    发送表情；伤害+1（已完成）
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecified then
      if not data.card.name == "v_ice__slash" then
        local address = "./packages/"..VslUtil.extensionName.."/image/skill/lixingyu"..math.random(3,4)
        room:setEmotion(player, address)
      end
      table.insert(data.nullifiedTargets, player.id)
      room:sendLog{
        type = "#v_bingshen",
        from = player.id,
        arg = self.name,
        -- arg2 = data.damage,
      }
    elseif event == fk.DamageInflicted then
      local address = "./packages/"..VslUtil.extensionName.."/image/skill/lixingyu"..math.random(7,9)
      room:setEmotion(player, address)
      data.damage = data.damage + 1
    end
  end,
}

--------------------------------------------------
--角色特性：一起恰冰沙
--------------------------------------------------

local v_characteristic_yiqiqiabingsha = fk.CreateTriggerSkill{
  name = "#v_characteristic_yiqiqiabingsha",
  anim_type = "special",
  --技能为锁定技，满足条件后强制发动
  frequency = Skill.Compulsory,
  events = {fk.GameStart},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self.name, true) then
      return false
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      local cids = {}
      -- for i = #room.void, 1, -1 do
      --   if Fk:getCardById(room.void[i]).name == "raid_and_frontal_attack" then
      --     local idRemoved = table.remove(room.void, i)
      --     table.insert(room.draw_pile, math.random(1, #room.draw_pile), idRemoved)
      --     room:setCardArea(idRemoved, Card.DrawPile, nil)
      --   end
      -- end
      for i = 1, 3, 1 do
        local card = room:printCard("v_ice__slash", Card.Club, i)
        table.insertIfNeed(cids, card.id)
      end
      local ram = math.random(1, #room.draw_pile + 1)
      room:moveCards({
        ids = cids,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonJustMove,
        skillName = self.name,
        drawPilePosition = ram,
      })
      room:sendLog{
				type = "#v_newcardintopile_log",
				from = player.id,
				card = cids,
				arg = self.name,
			} 
      room:doBroadcastNotify("UpdateDrawPile", #room.draw_pile)
    end
  end,
}

--------------------------------------------------
--璃星羽
--------------------------------------------------

local lixingyu_bingshayoulang = General(extension, "lixingyu_bingshayoulang", "individual", 4, 4, General.Bigender)
lixingyu_bingshayoulang:addSkill(v_bingsha)
lixingyu_bingshayoulang:addSkill(v_bingshen)

-- 加载本包的翻译包(load translations of this package)，这一步在本文档的最后进行。
-- dofile "packages/vupslash/i18n/init.lua"
dofile "packages/VslTest/i18n/init.lua"
  
-- return { extension } 

return extension